20 Payment Opcode Workflows

Learn about the Oracle Communications Billing and Revenue Management (BRM) payment opcode workflows.

Topics in this document:

Opcodes Described in This Chapter

Table 20-1 lists the opcodes described in this chapter.

Caution:

  • Always use the BRM API to manipulate data. Changing data in the database without using the API can corrupt the data.

  • Do not use SQL commands to change data in the database. Always use the API.

Table 20-1 Payment Opcodes Described in This Chapter

Opcode Topic

PCM_OP_ACT_POL_EVENT_NOTIFY

Triggering Top-ups

PCM_OP_ACT_USAGE

BRM-Initiated Payment Processing

Receiving Payments

PCM_OP_AR_ACCOUNT_ADJUSTMENT

How BRM Handles Manual Standard Top-Ups

How BRM Handles Automatic Standard Top-Ups

PCM_OP_AR_ACCOUNT_WRITEOFF

Writing Off Payments

PCM_OP_AR_BILL_WRITEOFF

Writing Off Payments

PCM_OP_AR_ITEM_WRITEOFF

Writing Off Payments

PCM_OP_AR_REVERSE_WRITEOFF

Applying Payment Fees

PCM_OP_BILL_ITEM_REFUND

Refunding Payments

PCM_OP_BILL_ITEM_TRANSFER

BRM-Initiated Payment Processing

Triggering Payment Incentives

PCM_OP_BILL_MAKE_BILL

Granting Payment Incentives

PCM_OP_BILL_POL_CALC_PYMT_DUE_T

Calculating Payment Collection Dates

PCM_OP_BILL_RCV_PAYMENT

BRM-Initiated Payment Processing

Externally Initiated Payment Processing

Receiving Payments

Allocating Account Payments to Multiple Bill Units

How BRM Handles Manual Standard Top-Ups

PCM_OP_BILL_REVERSE

Reversing Payments

How Payments Are Recycled to and from Suspense

Retrieving Recycled Payments

How Suspended Payments Are Reversed

How Payments Are Reversed During Recycling

How Payments Are Removed As Unallocatable

PCM_OP_BILL_REVERSE_PAYMENT

BRM-Initiated Payment Processing

Reversing Payments

Reversing Payment Incentives

How Suspended Payments Are Reversed

How Payments Are Reversed During Recycling

How Payments Are Removed As Unallocatable

PCM_OP_BILL_SET_LIMIT_AND_CR Setting a Customer's Automatic Top-Up Threshold

PCM_OP_BILL_TRANSFER_BALANCE

How BRM Handles Manual Sponsored Top-Ups

How BRM Handles Automatic Sponsored Top-Ups

About Transferring Sponsored Top-Ups from Debit Balances

PCM_OP_CUST_AMEND_CREDITOR_INFO

How BRM Handles Mandate Information for SEPA Processing

Updating Creditor Information

PCM_OP_CUST_AMEND_MANDATE

How BRM Handles Mandate Information for SEPA Processing

PCM_OP_CUST_CANCEL_MANDATE

How BRM Handles Mandate Information for SEPA Processing

PCM_OP_CUST_COMMIT_CUSTOMER

Processing Credit Card Information during Account Creation

Implementing Automatic Standard Top-Ups

Implementing Manual Sponsored Top-Ups

Implementing Automatic Sponsored Top-Ups

PCM_OP_CUST_CREATE_PAYINFO

How BRM Handles Mandate Information for SEPA Processing

PCM_OP_CUST_CREATE_TOPUP

Setting Up Top-Up Information in an Account

Preparing an Account's Top-Up Information

Validating an Account's Top-Up Information

Modifying an Account's Top-Up Information

PCM_OP_CUST_UPDATE_CUSTOMER

Implementing Automatic Standard Top-Ups

Implementing Manual Sponsored Top-Ups

Implementing Automatic Sponsored Top-Ups

PCM_OP_CUST_DELETE_PAYINFO

How BRM Handles Mandate Information for SEPA Processing

PCM_OP_CUST_DELETE_TOPUP

Deleting Top-Ups

PCM_OP_CUST_FIND_PAYINFO

Finding Payment Info

PCM_OP_CUST_MODIFY_TOPUP

Setting Up Top-Up Information in an Account

Preparing an Account's Top-Up Information

Validating an Account's Top-Up Information

Modifying an Account's Top-Up Information

PCM_OP_PYMT_POL_OVER_PAYMENT

Handling Overpayments and Underpayments

PCM_OP_CUST_POL_PREP_NAMEINFO

About the Suspense Account

PCM_OP_CUST_POL_PREP_PAYINFO

Adding a Custom Payment Method

PCM_OP_CUST_POL_PREP_TOPUP

Preparing an Account's Top-Up Information

Validating an Account's Top-Up Information

Finding Sponsored Top-Up Groups

PCM_OP_PYMT_POL_UNDER_PAYMENT

Handling Overpayments and Underpayments

PCM_OP_CUST_POL_VALID_PAYINFO

Validating Credit Card and Direct Debit Transactions

Validating an Account's Top-Up Information

How BRM Handles Mandate Information for SEPA Processing

PCM_OP_CUST_PREP_CUSTOMER

Validating Credit Card and Direct Debit Transactions

PCM_OP_CUST_SET_NAMEINFO

About the Suspense Account

PCM_OP_CUST_SET_PAYINFO

How BRM Handles Mandate Information for SEPA Processing

PCM_OP_CUST_SET_STATUS

BRM-Initiated Payment Processing

PCM_OP_CUST_SET_TOPUP

Setting Up Top-Up Information in an Account

Finding Sponsored Top-Up Groups

Implementing Automatic Standard Top-Ups

Implementing Manual Sponsored Top-Ups

Implementing Automatic Sponsored Top-Ups

Setting an Account's Sponsored Top-Up Member Status and PIN

PCM_OP_PYMT_APPLY_FEE

BRM-Initiated Payment Processing

Externally Initiated Payment Processing

Applying Payment Fees

PCM_OP_PYMT_CHARGE

BRM-Initiated Payment Processing

Processing Credit Card Charges

Processing Direct Debit Charges

Checking the Results of BRM-Initiated Batch Payment Operations

PCM_OP_PYMT_CHARGE_CC

BRM-Initiated Payment Processing

Processing Credit Card Charges

Processing a Batch of Direct Debit Charges

PCM_OP_PYMT_CHARGE_DD

BRM-Initiated Payment Processing

Processing Direct Debit Charges

About Paymentech Direct Debit Implementation

Creating a Custom Direct Debit Implementation

Processing a Batch of Direct Debit Charges

PCM_OP_PYMT_CHARGE_DDEBIT

About Paymentech Direct Debit Implementation

PCM_OP_PYMT_COLLECT

Collecting Payments

BRM-Initiated Payment Processing

Externally Initiated Payment Processing

Receiving Payments

Validating Payments

About the Default Payment Validation Process

About Payment Validation Flags

How BRM Selects the Items to Which Payments Are Applied

Configuring Unconfirmed Payment Processing

Allocating Account Payments to Multiple Bill Units

Allocating Externally Initiated Payments by Due Amount

Refunding Payments

Checking the Results of BRM-Initiated Batch Payment Operations

Applying Payment Fees

Suspending Payments during Payment Processing

How Payments Are Recycled to and from Suspense

PCM_OP_PYMT_FIND_TOPUP_EVENTS

Finding Top-Up Events

Viewing Sponsored Top-Up History

PCM_OP_PYMT_GET_ACH_INFO

Processing Credit Card Information during Account Creation

PCM_OP_PYMT_GRANT_INCENTIVE

Processing Payment Incentives

Triggering Payment Incentives

Granting Payment Incentives

PCM_OP_PYMT_ITEM_TRANSFER

Externally Initiated Payment Processing

Receiving Payments

PCM_OP_PYMT_MBI_DISTRIBUTE

Allocating Account Payments to Multiple Bill Units

PCM_OP_PYMT_MBI_ITEM_SEARCH

Allocating Account Payments to Multiple Bill Units

PCM_OP_PYMT_POL_APPLY_FEE

Applying Payment Fees

Customizing Payment Fees

PCM_OP_PYMT_POL_CHARGE

BRM-Initiated Payment Processing

Customizing Payment Failure Reason Codes

PCM_OP_PYMT_POL_COLLECT

BRM-Initiated Payment Processing

Externally Initiated Payment Processing

Processing the Results of Credit Card Transactions

PCM_OP_PYMT_POL_GRANT_INCENTIVE

Granting Payment Incentives

PCM_OP_PYMT_POL_MBI_DISTRIBUTE

Allocating Account Payments to Multiple Bill Units

PCM_OP_PYMT_POL_OVER_PAYMENT

Externally Initiated Payment Processing

How BRM Selects the Items to Which Payments Are Applied

PCM_OP_PYMT_POL_PRE_COLLECT

BRM-Initiated Payment Processing

Externally Initiated Payment Processing

Allocating Account Payments to Multiple Bill Units

PCM_OP_PYMT_POL_PROVISION_INCENTIVE

Triggering Payment Incentives

PCM_OP_PYMT_POL_PURCHASE_DEAL

How BRM Handles Manual Standard Top-Ups

How BRM Handles Automatic Standard Top-Ups

Offering Discount Incentives with Top-Ups

PCM_OP_PYMT_POL_SPEC_COLLECT

Processing Credit Card Information during Account Creation

PCM_OP_PYMT_POL_SPEC_VALIDATE

Validating Credit Card and Direct Debit Transactions

PCM_OP_PYMT_POL_SUSPEND_PAYMENT

Validating Payments

Allocating Account Payments to Multiple Bill Units

Customizing Suspended Payment Distribution

PCM_OP_PYMT_POL_UNDER_PAYMENT

Externally Initiated Payment Processing

How BRM Selects the Items to Which Payments Are Applied

PCM_OP_PYMT_POL_VALIDATE

Validating Credit Card and Direct Debit Transactions

PCM_OP_PYMT_POL_VALIDATE_PAYMENT

Validating Payments

About the Default Payment Validation Process

About Payment Validation Flags

Allocating Account Payments to Multiple Bill Units

Allocating Externally Initiated Payments by Due Amount

Configuring Unconfirmed Payment Processing

Processing Paymentech Address Validation Return Codes

Suspending Payments during Payment Processing

Customizing Payment Suspense Validation

PCM_OP_PYMT_POL_VALID_VOUCHER

How BRM Handles Manual Standard Top-Ups

PCM_OP_PYMT_PROVISION_INCENTIVE

Processing Payment Incentives

PCM_OP_PYMT_RECOVER

Checking the Results of BRM-Initiated Batch Payment Operations

PCM_OP_PYMT_RECOVER_CC

Checking the Results of BRM-Initiated Batch Payment Operations

PCM_OP_PYMT_RECOVER_DD

Checking the Results of BRM-Initiated Batch Payment Operations

PCM_OP_PYMT_RECYCLE_PAYMENT

Allocating Account Payments to Multiple Bill Units

How Payments Are Recycled to and from Suspense

Retrieving Recycled Payments

How Payments Are Reversed During Recycling

PCM_OP_PYMT_RECYCLED_PAYMENTS_SEARCH

Reversing Payments

How Payments Are Recycled to and from Suspense

Retrieving Recycled Payments

PCM_OP_PYMT_REVERSE_INCENTIVE

Reversing Payments

Reversing Payment Incentives

PCM_OP_PYMT_SELECT_ITEMS

BRM-Initiated Payment Processing

Externally Initiated Payment Processing

About Payment Validation Flags

How BRM Selects the Items to Which Payments Are Applied

Handling Overpayments and Underpayments

Allocating Account Payments to Multiple Bill Units

Allocating Externally Initiated Payments by Due Amount

Applying Payment Fees

PCM_OP_PYMT_TOPUP

Triggering Top-ups

How BRM Handles Manual Standard Top-Ups

How BRM Handles Automatic Standard Top-Ups

How BRM Handles Manual Sponsored Top-Ups

How BRM Handles Automatic Sponsored Top-Ups

Implementing Manual Standard Top-Ups

Offering Discount Incentives with Top-Ups

About Transferring Sponsored Top-Ups from Debit Balances

PCM_OP_PYMT_VALIDATE

Validating Credit Card and Direct Debit Transactions

Processing Credit Card Information during Account Creation

PCM_OP_PYMT_VALIDATE_CC

Validating Credit Card and Direct Debit Transactions

PCM_OP_PYMT_VALIDATE_DD

Validating Credit Card and Direct Debit Transactions

PCM_OP_PYMT_VALIDATE_PAYMENT

Externally Initiated Payment Processing

Validating Payments

About the Default Payment Validation Process

Allocating Account Payments to Multiple Bill Units

Configuring Unconfirmed Payment Processing

Suspending Payments during Payment Processing

How Payments Are Recycled to and from Suspense

Collecting Payments

The main payment collection opcode is PCM_OP_PYMT_COLLECT. This opcode communicates with Payment Tool or a payment processor to perform payment collections, refunds, and reversals. It processes payments according to the payment processing type: BRM-initiated, or externally initiated.

PCM_OP_PYMT_COLLECT allocates the payment to open items for each bill unit specified for the account. This opcode calls other opcodes to validate payments and calls various policy opcodes that allow you to customize payment collection.

By default, BRM allocates payments automatically. You can prevent allocation by using the PIN_BILLFLG_DEFER_ALLOCATION flag (0x1000000) in the PCM_OP_PYMT_COLLECT input flist PIN_FLD_CHARGES array.

Finding Payments

PCM_OP_PYMT_ITEM_SEARCH searches for /item objects with a variable number of input parameters. This opcode calls PCM_OP_SEARCH based on the input argument fields.

For collective bills, PCM_OP_PYMT_ITEM_SEARCH checks the RejectPaymentsForPreviousBill business parameter.

If RejectPaymentsForPreviousBill is enabled, the opcode does not accept the payment. BRM sends such a payment to the suspense payment account.

If the RejectPaymentsForPreviousBill is disabled, the opcode can accept the payment. In such a case, the opcode searches for the bill in the history_bills objects. If the bill is located in the history_bills objects, the payment is accepted for the bill with the same POID as the bill being processed. If such a bill is not located in history_bills objects, the payment is sent to a suspense payment account.

BRM-Initiated Payment Processing

For BRM-initiated payment processing, the normal flow of PCM_OP_PYMT_COLLECT is as follows:

  1. Creates a batch checkpoint.

  2. Calls PCM_OP_PYMT_SELECT_ITEMS to identify the items to which the payments are applied. See "How BRM Selects the Items to Which Payments Are Applied".

  3. Calls PCM_OP_PYMT_POL_PRE_COLLECT, to perform policy checks before the charge, payment, or refund occurs after allocating the PIN_FLD_CHARGE array elements to open items.

    You can change the minimum credit card charge amount by modifying the default minimum payment amount in PCM_OP_PYMT_POL_PRE_COLLECT.

    You can also customize PCM_OP_PYMT_POL_PRE_COLLECT to retrieve soft descriptor information that enables you to display the name under which you do business (your DBA name), charge offer name, and customer service number on your customer's checking account or credit card statement.

  4. Calls PCM_OP_PYMT_CHARGE to perform a BRM-initiated payment transaction.

    PCM_OP_PYMT_COLLECT checks the /config/payment object to determine which opcode to call to retrieve the payment information from the Payment DM and to create the charge: PCM_OP_PYMT_CHARGE_CC or PCM_OP_PYMT_CHARGE_DD.

  5. For SEPA payments, creates the SEPA Direct Debit payment request (/sepa/dd).

  6. Calls PCM_OP_BLL_RCV_PAYMENT. PCM_OP_BLL_RCV_PAYMENT:

    1. Calls PCM_OP_ACT_USAGE to update the /event/billing/payment/ object.

    2. Calls PCM_OP_BILL_ITEM_TRANSFER to allocate each payment to open items for each bill unit (/billinfo object) specified for the account.

  7. Calls PCM_OP_PYMT_APPLY_FEE to apply payment fees. If a payment fee is applied, the POID of the payment fee event is added to the PCM_OP_PYMT_APPLY_FEE output flist.

  8. Calls PCM_OP_PYMT_POL_COLLECT, to process the result of a credit card transaction for a specified account bill unit. PCM_OP_PYMT_POL_COLLECT sends the charge result to the policy opcode which specifies both the result to be returned to the caller and the actions to be performed on the account's bill unit.

    For BRM-initiated payments, PCM_OP_PYMT_POL_COLLECT calls PCM_OP_CUST_SET_STATUS if the operation requires a status change.

  9. By using checkpoints, finalizes the batch.

Note:

The BRM-initiated payment collection utilities (pin_collect and pin_deposit) process payments for multiple bills associated with multiple bill units. To process externally initiated payments, such as checks and cash payments, for multiple bill units, write custom code that records the deposits you have received and calls PCM_OP_PYMT_COLLECT.

When PCM_OP_PYMT_COLLECT calls PCM_OP_PYMT_CHARGE, the input flist contains a PIN_FLD_SESSION_OBJ field, which defines the session in which the event occurred: either a payment batch event or a refund batch event.

The input flist also contains an array of specific operations to perform, so any number of operations can be batched together into a single call. The command is specified in each operation, so a single batch can contain a mixture of different commands.

The billing information for each operation, such as credit card number and expiration date, can be specified as options on the input flist. If it isn't specified, PCM_OP_PYMT_CHARGE retrieves the necessary information from the account objects specified in the operations. After it has all the data, the operations are forwarded to the opcode responsible for processing that payment method (for example, PCM_OP_PYMT_CHARGE_CC and PCM_OP_PYMT_CHARGE_DD for credit card charges and direct debit charges, respectively).

Note:

  • For security reasons, the credit card CVV2 and CID numbers are not stored in BRM. If the cc_collect entry is enabled, PCM_OP_PYMT_CHARGE passes the security information to the payment processor for authorization and collection only at time of account creation. When collecting payments, PCM_OP_PYMT_CHARGE does not pass the information. In addition, it omits the PIN_FLD_SECURITY_ID field from the PCM_OP_ACT_USAGE input flist so it is not written to the /event/billing/charge/cc object. The result is that the CVV2/CID information is stored in the database with a NULL value.

  • BRM supports direct debit transactions from checking accounts only.

Each of the commands listed below in Table 20-2 can be run as an operation.

Table 20-2 Commands to Perform Transactions

Command Description

PIN_CHARGE_CMD_VERIFY

Verify the address information.

PIN_CHARGE_CMD_AUTH_ONLY

Authorize a charge. The credit limit is decreased on the credit card, but no charge is posted.

PIN_CHARGE_CMD_CONDITION

Authorize and deposit a charge.

PIN_CHARGE_CMD_DEPOSIT

Deposit a previously authorized charge.

PIN_CHARGE_CMD_RECOVER_PAYMENT

Recovers payments by using outstanding checkpoints.

PIN_CHARGE_CMD_REFUND

Refund a charge.

PIN_CHARGE_CMD_RESUBMIT

Resubmit the batch of charges.

PIN_CHARGE_CMD_RFR

For transactional payments, requests the RFR file to retrieve payments.

For nontransactional payments, reads the RFR file to retrieve payments.

For each operation specified, the result of the operation is stored in the corresponding /event/billing/charge object.

The result is stored both as a numeric value returned by the payment processor, and as an enumerated result. The enumerated result should generally be used by applications to determine what happened because its values are independent of which settlement house was used.

Possible result values for an operation are shown in Table 20-3:

Table 20-3 Result Values for Operation

InputPIN_FLD_RESULT OutputPIN_FLD_RESULT OutputPIN_FLD_DESCR

PIN_CHARGE_RES_PASS

PIN_RESULT_PASS

Validation successful

PIN_CHARGE_RES_SRVC_UNAVAIL

PIN_RESULT_PASS

Validation successful

PIN_CHARGE_RES_FAIL_ADDR_AVS

PIN_RESULT_FAIL

Unable to verify address

PIN_CHARGE_RES_FAIL_ADDR_LOC

PIN_RESULT_PASS

Street address mismatch

PIN_CHARGE_RES_FAIL_ADDR_ZIP

PIN_RESULT_FAIL

ZIP code mismatch

PIN_CHARGE_RES_FAIL_CARD_BAD

PIN_RESULT_FAIL

Credit card number not valid

PIN_CHARGE_RES_FAIL_DECL_SOFT

PIN_RESULT_FAIL

General soft decline

Card failed credit check

PIN_CHARGE_RES_FAIL_DECL_HARD

PIN_RESULT_FAIL

General hard decline

Card failed credit check

PIN_CHARGE_RES_FAIL_NO_ANS

PIN_RESULT_FAIL

No answer from settlement house

Unable to validate now

PIN_CHARGE_RES_CHECKPOINT

PIN_RESULT_FAIL

Unable to validate now

PIN_CHARGE_RES_CVV_BAD

PIN_RESULT_FAIL

Security ID check failed

General soft declines are failures that can be retried later with possible success. This includes reasons like insufficient credit limit and other transitory causes. General hard declines are failures that are unlikely to succeed if retried. These include reasons like lost and stolen credit card and chronic payment failures.

Note:

By default, account balances are not updated if there is a decline. To update account balances when a decline occurs, you must customize PCM_OP_PYMT_POL_CHARGE.

You can send multiple charges in one call by using the PIN_FLD_CHARGES array on the input flist. This array is designed for batch processing; you just make one call to PCM_OP_PYMT_CHARGE for a whole list of charges (or accounts to charge). The following entries on the PCM_OP_PYMT_CHARGE input flist are of special interest:

  • The PIN_FLD_POID entry at the top of the input flist is only used for routing; it only requires a correct (user) database number.

  • The PIN_FLD_ACCOUNT_OBJ entry is the POID of the account actually being charged (verified) by this element of the PIN_FLD_CHARGES array. In a batch, this POID is presumably different for every element.

If the PCM_OPFLG_CALC_ONLY flag is set, the opcode does not change any fields in the database and does not create an /event/billing/charge object. However, it does provide a charge calculation to the caller by returning the fields that would have been used to create the event object and the charge item.

Note:

Do not set the PCM_OPFLG_CALC_ONLY flag if you are connected to a payment processor, for example Paymentech. This may cause the charge to be sent to the credit card company, even though the charge is not created in BRM. This may result in a double charge on the account.

Initiating a Charge

PCM_OP_PYMT_CHARGE performs a BRM-initiated payment transaction.

PCM_OP_PYMT_CHARGE is called by PCM_OP_PYMT_COLLECT, and is the main entry point opcode for all BRM-initiated payment activities.

The input flist contains an array of specific operations to perform, so any number of operations can be batched together into a single call. The command is specified in each operation, so a single batch can contain a mixture of different commands.

PCM_OP_PYMT_CHARGE calls the opcode responsible for processing the relevant payment method (for example, PCM_OP_PYMT_CHARGE_CC and PCM_OP_PYMT_CHARGE_DD for credit card charges and direct debit charges, respectively).

PCM_OP_PYMT_CHARGE works as follows:

  1. Opens a transaction.

  2. Using checkpoints, creates the /event/billing/charge event for each payment.

  3. Calls PCM_OP_PYMT_CHARGE_CC or PCM_OP_PYMT_CHARGE_DD, depending on the payment method, to process the charges from the payment DM.

  4. Updates the checkpoint in the charge event for each transaction received from the payment DM.

  5. For each PIN_FLD_CHARGES in the input flist:

    1. Closes billing for the account.

    2. Creates a payment item and records the account number, bill number, and transaction ID from the input flist, and the fact that the money has been received.

      Important:

      The maximum length of a payment transaction ID is 16 characters for BRM-initiated payments and 30 characters for externally initiated payments. If your company generates transaction IDs by appending characters to the payment batch IDs, ensure that the batch IDs are short enough to be within the limit after the additional characters are appended. If the payment transaction ID does not comply with the length restrictions, BRM does not generate an ID for the payment. (BRM-initiated payment transaction IDs are restricted by Paymentech processing requirements.)

    3. Adds the PIN_FLD_STATUS value in the output flist.

      For failed payments, sets the PIN_FLD_STATUS value to PIN_PYMT_FAILED. For successful payments, sets the PIN_FLD_STATUS value to PIN_PYMT_SUCCESS.

    4. Calls PCM_OP_PYMT_POL_CHARGE to update the reasons array. PCM_OP_PYMT_POL_CHARGE provides the ability to map the online and offline payment result to the payment status and the reason IDs defined in the /strings object. In the output flist PIN_FLD_REASONS array, the array of PIN_FLD_REASON_ID fields contains the failure reasons sent by the payment processor. You can configure PCM_OP_PYMT_POL_CHARGE to apply fees for failed credit card and direct debit transactions based on the reason for failure.

    5. Sends the payment status and the reasons array (PIN_FLD_REASON_ID and PIN_FLD_REASON_DOMAIN_ID) to PCM_OP_PYMT_COLLECT.

    6. For payments with a successful status, applies the charge to the customer's account. For payments with a failed status, sends the PIN_FLD_STATUS value to PCM_OP_PYMT_APPLY_FEE to create the payment fees.

  6. Closes the transaction.

Processing Credit Card Charges

To perform a credit card charge, PCM_OP_PYMT_CHARGE calls PCM_OP_PYMT_CHARGE_CC.

This opcode supports all commands handled by PCM_OP_PYMT_CHARGE.

The PCM_OP_PYMT_CHARGE_CC input flist contains the PIN_FLD_SESSION_OBJ field, which references either the /event/billing/batch/payment or /event/billing/batch/refund object. This determines the batch type being submitted (payment or refund).

The PCM_OP_PYMT_CHARGE_CC input flist contains an array of specific operations to perform, so any number of operations can be batched together into a single call. The command is specified in each operation, so a single batch can contain a mixture of different commands. This opcode supports all commands handled by PCM_OP_PYMT_CHARGE.

The operations are forwarded to the credit card processing Data Manager (for example, the Paymentech DM) for processing.

With most credit card payment services, performing an authorization is much faster than a conditional deposit (authorization plus deposit). Thus, for applications where latency is important, it may be desirable to perform just the authorization step in real-time. BRM daily billing performs the necessary deposits for all outstanding authorizations from the previous day. This removes a significant amount of latency from the real-time process, but still authorizes the charge so it is guaranteed to deposit successfully.

The set of Paymentech return codes handled by BRM is listed in the BRM_home/sys/dm_fusa/fusa_codes file.

Unless the PCM_OPFLG_CALC_ONLY flag is specified, PCM_OP_PYMT_CHARGE_CC creates an /event/billing/charge/cc object for each operation. If an array of operations was specified, then more than one event object is created. The event objects are created even if the credit card operations cannot be performed.

Note:

Do not set the PCM_OPFLG_CALC_ONLY flag if you are connected to a payment processor, for example, Paymentech. This may cause the charge to be sent to the credit card company, even though the charge is not created in BRM. This may result in a double charge on the account.

Processing the Results of Credit Card Transactions

To process the result of a credit card transaction for a specified account, use PCM_OP_PYMT_POL_COLLECT.

This opcode does the following:

  • Sets the PIN_FLD_RESULT and PIN_FLD_DESCR values returned in the output flist.

  • Specifies the payment events (for example, payment fees, payment reversals, and write-off reversals) to be performed on the account in the PIN_FLD_EVENTS array.

  • Based on the results of the credit card transaction, specifies the actions to be performed on the account by returning a PIN_FLD_ACTIVITIES array.

PCM_OP_PYMT_POL_COLLECT is called by PCM_OP_PYMT_COLLECT after the credit card has been charged.

PCM_OP_PYMT_POL_COLLECT sets the PIN_FLD_RESULT and PIN_FLD_DESCR values returned in the output flist. It also specifies the actions to be performed on the account based on the results of the credit card transaction by returning a PIN_FLD_ACTIVITIES array.

The default behavior of PCM_OP_PYMT_POL_COLLECT is determined by the PIN_FLD_RESULT field passed in on the input flist.

  • If the result is successful, PIN_CHARGE_RES_PASS is passed in. Depending on the PIN_FLD_COMMAND passed in on the flist, PCM_OP_PYMT_POL_COLLECT sets the PIN_FLD_DESCR value as shown in Table 20-4:

    Table 20-4 Input and Output Values

    Input PIN_FLD_RESULT Input PIN_FLD_COMMAND Output PIN_FLD_RESULT Output PIN_FLD_DESCR

    PIN_CHARGE_RES_PASS

    PIN_CHARGE_CMD_AUTH_ONLY

    PIN_RESULT_PASS

    Authorization successful

    PIN_CHARGE_RES_PASS

    PIN_CHARGE_CMD_CONDITION

    PIN_RESULT_PASS

    Authorization & deposit successful

    PIN_CHARGE_RES_PASS

    PIN_CHARGE_CMD_DEPOSIT

    PIN_RESULT_PASS

    Deposit successful

    PIN_CHARGE_RES_PASS

    PIN_CHARGE_CMD_REFUND

    PIN_RESULT_PASS

    Refund successful

    PCM_OP_PYMT_POL_COLLECT then specifies actions to be performed on the account based on the PIN_FLD_COMMAND, the payment amount, and the pending receivable amount as shown in Table 20-5:

    Table 20-5 PCM_OP_PYMT_POL_COLLECT Actions

    Input PIN_FLD_COMMAND Actions When Payment >= Pending Receivable Action When Payment < Pending Receivable

    PIN_CHARGE_CMD_AUTH_ONLY

    PIN_CHARGE_CMD_CONDITION

    PIN_CHARGE_CMD_REFUNDS

    • Clear the pending receivable amount.

    • If the account status is currently set to inactive, change it to active.

    • Set the status flag value to PIN_STATUS_FLAG_DEBT.

    Credit toward outstanding bill.

    PIN_CHARGE_CMD_DEPOSIT

    No action specified

    No action specified

  • If the result is unsuccessful, and PIN_CHARGE_RES_FAIL_CARD_BAD or PIN_CHARGE_RES_FAIL_DECL_HARD are passed in, PCM_OP_PYMT_POL_COLLECT sets the PIN_FLD_RESULT value and the PIN_FLD_DESCR description, and then specifies these actions as shown in Table 20-6:

    Table 20-6 Input and Output Values

    Input PIN_FLD_RESULT Output PIN_FLD_RESULT Output PIN_FLD_DESCR Action

    PIN_CHARGE_RES_FAIL_CARD_BAD

    PIN_CHARGE_RES_FAIL_DECL_HARD

    PIN_RESULT_FAIL

    Credit card operation declined

    Set account status to inactive.

    Set status flag value to PIN_STATUS_FLAG_DEBT.

The PIN_FLD_PAYMENT_REASONS array in the input flist contains a PIN_FLD_PAYMENT_REASONS array, which contains information related to failed payments. These values are recorded in the FAILED_ACCOUNTS array of the /process_audit/billing object.

Note:

If a single payment is submitted for multiple bills, and fails, it is stored as multiple FAILED_ACCOUNTS arrays.

The remaining input PIN_FLD_RESULT values are implemented in the same way. PCM_OP_PYMT_POL_COLLECT sets the output PIN_FLD_RESULT value and the PIN_FLD_DESCR description, and then reads the item for the account to determine if there is an amount that is 30 days past due. If so, it specifies the following actions shown in Table 20-7:

Table 20-7 Input and Output Values

Input PIN_FLD_RESULT Output PIN_FLD_RESULT Output PIN_FLD_DESCR Action

PIN_CHARGE_RES_FAIL_DECL_SOFT

PIN_CHARGE_RES_FAIL_ADDR_AVS

PIN_CHARGE_RES_FAIL_ADDR_LOC

PIN_CHARGE_RES_FAIL_ADDR_ZIP

PIN_CHARGE_RES_FAIL_NO_ANS

PIN_CHARGE_RES_SRVC_UNAVAIL

PIN_RESULT_FAIL

Credit card operation declined

Set account status to inactive.

Set status flag value to PIN_STATUS_FLAG_DEBT.

You can customize PCM_OP_PYMT_POL_COLLECT to specify any of these actions:

  • clear_pending

  • set_status

  • cease_billing

For example, to discontinue billing an account after a determined period of inactivity, specify the cease_billing action. The default implementation does not specify the cease_billing action for any input PIN_FLD_RESULT values.

Processing Paymentech Address Validation Return Codes

Paymentech provides return codes when verifying customer addresses. To change how BRM responds to validation return codes, edit PCM_OP_PYMT_POL_VALIDATE source.

For example, by default a invalid address does not cause a validation failure. You can change the policy to fail validation if the customer's street address is wrong. For example, change the following code:

case PIN_CHARGE_RES_FAIL_ADDR_LOC:
   /* street address failure is acceptable */
   result = PIN_RESULT_PASS;
   descr = "street address not correct";
   break;

To this:

case PIN_CHARGE_RES_FAIL_ADDR_LOC:
   /* street address failure is acceptable */
   result = PIN_RESULT_FAIL;
   descr = "street address not correct";
   break;

PCM_OP_PYMT_POL_VALIDATE returns the result of validating a credit card transaction in the PIN_FLD_VENDOR_RESULTS field, including a description of that result. You can customize credit card validations based on the response from ACH by passing a PIN_FLD_ VENDOR_RESULTS value in the input flist. For example, you can set the validation to pass or fail, or turn on logging based on the results from the ACH.

PCM_OP_PYMT_VALIDATE calls PCM_OP_PYMT_POL_VALIDATE during customer account creation to determine the success or failure of credit card validation.

You can change both the PIN_FLD_RESULT and PIN_FLD_DESCR values to modify BRM responses to validation results returned in PIN_FLD_VENDOR_RESULTS. For example, if your company does not want to proceed with a transaction when the result is PIN_CHARGE_RES_SRV_UNAVAIL, change the PIN_FLD_RESULT_PASS value to PIN_FLD_RESULT_FAIL and change the PIN_FLD_DESCR value to “Service unavailable".

If the PIN_FLD_RESULT value passed in on the input flist is NULL, PCM_OP_PYMT_POL_VALIDATE does nothing. Otherwise, the default validation result depends on the PIN_FLD_RESULT value. See Table 20-3.

Note:

If you add custom result values to your system, do not assign them the following result codes, which are reserved by BRM: 0 - 17, 777, 888, 999, 1000 - 1017, 1777, and 1999.

You can turn off credit card validation. If the credit card payment service is not available and you still want to register customers, you must isolate those accounts for later credit card authorization. Modify the PCM_OP_PYMT_POL_VALIDATE policy opcode file either to save a list of permissive account creations or to send email to the system administrator. Alternatively, you can write a simple application to periodically check accounts and flag the ones that have been registered without verification.

Processing AVS Validations for International Credit Cards

By default, BRM sends a customer's name, address, and ZIP code for validation when processing credit card charges. If you use the Address Verification System (AVS) to validate addresses, only credit cards with addresses in the United States and Canada pass validation.

To change how BRM handles credit card address verifications, do one of the following:

  • Set the cc_validate flag in the CM's pin.conf file to 0. This disables the address validation process by Paymentech for all credit cards, including United States and Canada credit cards.

  • Set the cc_validate flag in the CM's pin.conf file to 1 and modify PCM_OP_PYMT_POL_VALIDATE to ignore all AVS failure response codes for other countries. This changes how BRM responds to Paymentech's validation return codes for countries other than the United States and Canada.

Processing Direct Debit Charges

BRM supports direct debit transactions from customer checking accounts only. To perform a batch of Paymentech direct debit transactions, PCM_OP_PYMT_CHARGE calls PCM_OP_PYMT_CHARGE_DD.

PCM_OP_PYMT_CHARGE_DD supports all commands handled by PCM_OP_PYMT_CHARGE, except that it does not create a payment structure and handles transaction charges of $1 only.

PCM_OP_PYMT_CHARGE_DD is used for the Paymentech direct debit implementation shipped with BRM, and is available for you to use in creating a custom direct debit implementation for the bank or payment clearing house you choose.

Note:

Debit cards that require a personal identification number (PIN) are not supported.

About Paymentech Direct Debit Implementation

PCM_OP_PYMT_CHARGE_DDEBIT performs a debit card transaction. This opcode is used for the Paymentech direct debit implementation, and is available for creating a custom direct debit implementation for the bank or payment clearing house you choose. Unless the PCM_OPFLG_CALC_ONLY flag is specified, PCM_OP_PYMT_CHARGE_DDEBIT creates an /event/billing/charge/ddebit object for each operation. If an array of operations is specified, then more than one event object is created.

PCM_OP_PYMT_CHARGE_DDEBIT supports all commands handled by PCM_OP_PYMT_CHARGE.

Important:

Debit cards that require a personal identification number (PIN) are not supported.

Note:

Do not set the PCM_OPFLG_CALC_ONLY flag if you are connected to a payment processor, for example, Paymentech. This may cause the charge to be sent to the credit card company, even though the charge is not created in BRM. This may result in a double charge on the account.

Creating a Custom Direct Debit Implementation

By default, PCM_OP_PYMT_CHARGE_DD returns direct debit payment information, a charge status, and a payment status to the calling opcode for updating respective events. Effectively this opcode performs a loopback operation that you must change before you can implement direct debit charging. It does not output transaction data for a direct debit clearinghouse. BRM users must create an application to extract the information from the database for a specific direct debit clearinghouse.

Processing a Batch of Direct Debit Charges

To perform a batch of Paymentech direct debit transactions, PCM_OP_PYMT_CHARGE calls PCM_OP_PYMT_CHARGE_DD. The processing is performed on a per-batch basis; only one command and one payment method can exist in the same batch.

PCM_OP_PYMT_CHARGE_DD supports all commands handled by PCM_OP_PYMT_CHARGE, except that it does not create a payment structure and handles transaction charges of $1 only.

The input flist contains a PIN_FLD_SESSION_OBJ field, which defines the session in which the event occurred: either a payment batch event or a refund batch event (/event/billing/batch/payment or /event/billing/batch/refund).

Unless the PCM_OPFLG_CALC_ONLY flag is specified, PCM_OP_PYMT_CHARGE_DD creates an /event/billing/charge/dd object for each operation. If an array of operations was specified, then more than one event object is created. The event objects are created even if the direct debit operations cannot be performed.

Note:

Do not set the PCM_OPFLG_CALC_ONLY flag if you are connected to a payment processor, for example, Paymentech. This may cause the charge to be sent to the credit card company, even though the charge is not created in BRM. This may result in a double charge on the account.

The set of Paymentech return codes handled by BRM is listed in the BRM_home/sys/dm_fusa/fusa_codes file. These codes can be modified.

Checking the Results of BRM-Initiated Batch Payment Operations

To check the results of batch payment operations, set the PIN_FLD_COMMAND value in the PCM_OP_PYMT_COLLECT input flist to PIN_CHARGE_CMD_RECOVER_PAYMENT. This causes PCM_OP_PYMT_CHARGE to call PCM_OP_PYMT_RECOVER.

PCM_OP_PYMT_RECOVER posts the results of charges for which no information was returned.

PCM_OP_PYMT_RECOVER calls the following opcodes:

  • To check the results of a batch of credit card charges, PCM_OP_PYMT_RECOVER_CC calls PCM_OP_PYMT_RECOVER_CC. This opcode posts results of credit card charges for which no information was returned.

    PCM_OP_PYMT_RECOVER_CC is specific to the Paymentech DM.

  • To check the results of a batch of direct debit charges, PCM_OP_PYMT_RECOVER_CC calls PCM_OP_PYMT_RECOVER_DD. This opcode posts results of direct debit charges for which no information was returned. The results are passed back and used for transaction reconciliation.

    PCM_OP_PYMT_RECOVER_DD is specific to the Paymentech DM.

Validating Credit Card and Direct Debit Transactions

To validate credit card and direct debit transactions, use PCM_OP_PYMT_VALIDATE. This opcode is called by PCM_OP_CUST_PREP_CUSTOMER and PCM_OP_CUST_POL_VALID_PAYINFO during account creation.

PCM_OP_PYMT_VALIDATE calls PCM_OP_PYMT_POL_VALIDATE to determine the success or failure of a BRM-initiated transaction validation.

PCM_OP_PYMT_VALIDATE reads the /config/payment storable class to determine the transaction type and the opcode to call, and then calls the appropriate opcode to validate the transaction.

  • Credit card transactions: PCM_OP_PYMT_VALIDATE_CC.

    PCM_OP_PYMT_VALIDATE_CC performs a batch of online credit card validations and applies the validation policy to the results.

  • Direct debit transactions: PCM_OP_PYMT_VALIDATE_DD.

    PCM_OP_PYMT_VALIDATE_DD performs a batch of online direct debit validations and applies the validation policy to the results. PCM_OP_PYMT_VALIDATE_DD calls the appropriate DM to process validations, then returns the results to the Internet.

    Note:

    BRM supports direct debit transactions from checking accounts only.

For both opcodes, the input flist contains an array of specific operations to perform, so any number of operations can be batched together into a single call. The command is specified in each operation, so a single batch can contain different commands. The PIN_FLD_SESSION_OBJ in the input flist is either /event/billing/batch/refund or /event/billing/batch/payment, depending on the batch type: payment or refund.

In addition, PCM_OP_CUST_PREP_CUSTOMER calls PCM_OP_PYMT_POL_SPEC_VALIDATE to determine whether a customer's payment information needs to be validated during account creation. If validation is required, PCM_OP_CUST_PREP_CUSTOMER calls PCM_OP_PYMT_VALIDATE to perform the operation. If validation fails, the results are transformed to be consistent with the results used to describe account creation failure results and are then returned on the output flist.

When validating a credit card at account creation, BRM needs an account to validate the card with. By default, this is the root account. You cannot store this information with each account because the credit card validation is done before the account is created.

Processing Credit Card Information during Account Creation

During the account creation process, PCM_OP_CUST_COMMIT_CUSTOMER passes credit card information to PCM_OP_PYMT_VALIDATE and PCM_OP_PYMT_COLLECT, which collect any credit card payments charged at account creation and validate the credit card information returned by the payment processor.

  • PCM_OP_PYMT_COLLECT calls PCM_OP_PYMT_POL_SPEC_COLLECT, which passes the bill unit associated with the payment and returns a list of open items to be paid in the PIN_FLD_ITEMS array.

  • calls PCM_OP_PYMT_GET_ACH_INFO to retrieve the Automated Clearing House (ACH) information. PCM_OP_PYMT_POL_SPEC_COLLECT allows you to determine whether to charge the customer immediately for all or part of the current account balances during account creation.

  • PCM_OP_PYMT_GET_ACH_INFO retrieves ACH information from the /config/ach object. It uses the ACH vendor name or element ID in the input flist to determine which element in the ACH_INFO array should be used.

If the cc_collect value in the CM pin.conf file is set to 1, during account creation for credit card accounts, the total due amount for the account is charged immediately and the payment is allocated immediately to all open bill items. Therefore, after the account is created, it will have no pending amount due and no unapplied payments.

Storing Card Credentials for Future Transactions

To store a customer's credit card credentials for future transactions, use PCM_OP_PYMT_COLLECT.

This opcode does the following:

  1. Receives the PIN_FLD_TRANSACTIONS array from the following opcodes when a VISA, MasterCard, Diners, Discover, JCB, or American Express card is registered for payment:

    • PCM_OP_CUST_COMMIT_CUSTOMER: This opcode passes the PIN_FLD_TRANSACTIONS array as input when you register a new customer with Credit Card as the default payment method and either credit card tokenization is enabled or the cc_validate or cc_collect flag is enabled in the CM pin.conf file.

    • PCM_OP_CUST_SET_PAYINFO: This opcode passes the PIN_FLD_TRANSACTIONS array as input when you set Credit Card as the default payment method for an account.

    • PCM_OP_CUST_CREATE_PAYINFO: This opcode passes the PIN_FLD_TRANSACTIONS array as input when you add a new credit card and set that as the default payment method for the account.

  2. Accepts the card information in the PIN_FLD_TRANSACTIONS array, adds missing information as required, and then passes the information as input to the PCM_OP_PYMT_POL_PRE_COLLECT policy opcode.

    Note:

    You can add, update, or remove the card information in the PIN_FLD_TRANSACTIONS array by customizing the PCM_OP_PYMT_POL_PRE_COLLECT policy opcode.

  3. Receives the updated card information and the PIN_FLD_CHARGES array from the PCM_OP_PYMT_POL_PRE_COLLECT policy opcode.

  4. Sends the card information in the PIN_FLD_TRANSACTIONS array to the Paymentech DM by calling the PCM_OP_PYMT_CHARGE or PCM_OP_PYMT_CHARGE_CC opcode.

    The Paymentech DM appends the required records based on the information received and sends the transactions to Paymentech. If the transaction is successful, the Paymentech DM retrieves the TXID from the Paymentech response and passes it to the PCM_OP_PYMT_COLLECT opcode.

  5. Accepts the TXID received from the Paymentech DM and stores it in the PIN_FLD_TRANSACTIONS array in the /payinfo/cc object for future transactions.

Purging Card Credentials

When an account's default payment method is Credit Card, PCM_OP_PYMT_COLLECT stores the card credentials for each bill unit in the PIN_FLD_TRANSACTIONS array of the /payinfo/cc object.

If the default payment method is changed to any other method or card, the PIN_FLD_TRANSACTIONS array in the /payinfo/cc object is automatically purged from the database if the account payments are not in cardholder-initiated installments. If the payments are in cardholder-initiated installments, you must delete the /payinfo/cc object's PIN_FLD_TRANSACTIONS array manually after the payment is made for the last installment.

About Credit Card Payment Confirmation Numbers

When a credit card payment completes successfully, BRM returns a confirmation number that the customer can use later to identify the payment. BRM uses the payment item number as the confirmation number.

PCM_OP_PYMT_COLLECT returns the confirmation number in the PIN_FLD_ITEM_NO output flist field of the PIN_FLD_RESULTS array.

Externally Initiated Payment Processing

For externally initiated payment processing, the normal flow of PCM_OP_PYMT_COLLECT is as follows:

  1. Calls PCM_OP_PYMT_VALIDATE_PAYMENT to determine the status of the payment records. See "Validating Payments" for more information.

  2. Calls PCM_OP_PYMT_POL_PRE_COLLECT, to perform policy checks before the charge, payment, or refund occurs after allocating the PIN_FLD_CHARGE array elements to open items.

  3. Calls PCM_OP_PYMT_SELECT_ITEMS to identify the items to which the payments in the batch are applied. See "How BRM Selects the Items to Which Payments Are Applied".

    If necessary, PCM_OP_PYMT_COLLECT then calls PCM_OP_PYMT_POL_OVER_PAYMENT and PCM_OP_PYMT_POL_UNDER_PAYMENT, to allocate overpayment and underpayment of funds, respectively.

  4. Calls the following opcodes:

    • Calls PCM_OP_BLL_RCV_PAYMENT to create the /event/billing/payment/pay_type object.

      If the payment status is marked as a failed unconfirmed payment, PCM_OP_BILL_REVERSE_PAYMENT reverses the unconfirmed successful payments that have a value of PIN_PYMT_FAILED in the PIN_FLD_STATUS field. The PIN_FLD_AMOUNT value in the input flist CHARGES array is set to the value of PIN_FLD_AMOUNT_ORIGINAL_PAYMENT, and the value of PIN_FLD_AMOUNT is set to 0.

    • Calls PCM_OP_PYMT_ITEM_TRANSFER to allocate the payment to open items.

    • Calls PCM_OP_PYMT_APPLY_FEE to record failed payments and apply payment fees. If a payment fee is applied, the POID of the payment fee event is added to the PCM_OP_PYMT_APPLY_FEE output flist.

    • If the cease_billing action was received, calls PCM_OP_CUST_SET_BILLINFO to change the status of the bill unit.

  5. If mandated by the policy FM, calls PCM_OP_PYMT_POL_COLLECT to perform the following actions listed in Table 20-8, which are based on the payment result:

    Table 20-8 PCM_OP_PYMT_POL_COLLECT Policy Opcode Actions

    Action Description

    clear_pending

    Apply the payment to reduce the pending receivable of the bill unit by the amount specified.

    set_status

    Change the bill unit's status to that given, using the reasons indicated by the flags.

    issue_refund

    Apply a refund by crediting the bill unit with the refund amount specified.

    cease_billing

    Discontinue billing an account after a determined period of inactivity by marking the given bill unit as no longer billed.

  6. Creates the final batch.

Receiving Payments

When payments are received in BRM, they are processed by PCM_OP_PYMT_COLLECT. To record the payments, PCM_OP_PYMT_COLLECT calls PCM_OP_BILL_RCV_PAYMENT. PCM_OP_BILL_RCV_PAYMENT records the payment items and events and updates account balances by calling PCM_OP_BILL_ITEM_TRANSFER. If there is excess money after paying the item list off, PCM_OP_BILL_RCV_PAYMENT adds that amount to the sub-balance as a credit. If there is no sub-balance, one is created.

  • When posting a suspended payment, PCM_OP_BILL_RCV_PAYMENT stores the reason code, action owner code, and original reason code for the payment in the payment event's PIN_FLD_EVENT_MISC_DETAILS array. The reason codes are passed in from the PCM_OP_PYMT_COLLECT input flist's PYMT_REASONS array.

    The PIN_FLD_EVENT_MISC_DETAILS array uses specific element IDs as follows:

    • Array Element 0: Stores the reason code used to determine the G/L ID of the payment being moved to the payment suspense account.

    • Array Element 1: Stores the action owner code for suspended or failed payments.

    • Array Element 2: Stores the original reason code for failed payments that BRM suspended. This ensures that the reason initially associated with the financial failure is not lost if BRM places the payment in suspense. Element 2 is used only for Payment Suspense Manager; if payment suspense is not enabled, only element 0 is present.

    When the failed payment leaves suspense and PCM_OP_BILL_RCV_PAYMENT creates new payment objects to record the corrected payment, Elements 0 and 1 are no longer needed. The object does not contain the elements 0 and 1 recorded for suspense, and Element 2 becomes the new Element 0.

  • When processing multiple voucher top-ups that include noncurrency balances, PCM_OP_BILL_RCV_PAYMENT retrieves the noncurrency balance impacts from the PIN_FLD_TOPUP_RESOURCE_INFO substruct in the PCM_OP_PYMT_COLLECT input flist and passes them to PCM_OP_ACT_USAGE so that they are recorded in the corresponding /event/billing/payment/voucher object. See "Processing Top-Ups" for more information.

  • When PCM_OP_BILL_RCV_PAYMENT is called by Payment Tool, Payment Tool first calls PCM_OP_PYMT_SELECT_ITEMS to identify the list of items to apply this payment to.

PCM_OP_BILL_RCV_PAYMENT uses the PIN_FLD_SESSION_OBJ field in the input flist to reference the type of session in which the event occurred: either /event/billing/batch/refund or /event/billing/batch/payment, depending on the batch.

Validating Payments

Before payments can be processed and posted by BRM, they must pass validation. Payment validation is initiated automatically, through the payment gateway, or manually, by a payment clerk. When a payment arrives in BRM, PCM_OP_PYMT_COLLECT calls PCM_OP_PYMT_VALIDATE_PAYMENT to perform the validation. BRM validates the payment information in the input flist and, in the output flist, indicates whether the opcode successfully performed the validation.

The PIN_FLD_STATUS value returned by PCM_OP_PYMT_VALIDATE_PAYMENT indicates whether the payment arrived in BRM as successful or failed for financial reasons. If you have the Payment Suspense Manager functionality installed, payments can also arrive as suspended.

  • If the payment is successful and passes the validation process, the PIN_FLD_STATUS value is PIN_PYMT_SUCCESS, and BRM posts the payment to the account.

  • If the payment meets the validation criteria, but fails for financial reasons, the PIN_FLD_STATUS value is PIN_PYMT_FAILED, and BRM posts the payment to the account as a failed payment.

  • If the payment status is marked for suspense, the PIN_FLD_STATUS value is PIN_PYMT_SUSPENSE, and PCM_OP_PYMT_COLLECT calls PCM_OP_PYMT_POL_SUSPEND_PAYMENT to process the payment. PCM_OP_PYMT_POL_SUSPEND_PAYMENT places a payment in suspense by enriching the flist so that the payment can be directed to the payment suspense account. It then calls the opcodes that post the payment to this account and create objects to record the suspended payment. The event object contains all information about the payment and its suspense, including the account number, bill number, transaction ID, and any associated reason codes or action owner codes. This information can be used to investigate why the payment failed the validation process and who is responsible for resolving the problem.

If an account payment is made to an account with multiple bill units, PCM_OP_PYMT_POL_VALIDATE_PAYMENT validates that the payment is an account payment and the account has multiple bill units. If the payment is successful and passes the validation process, it adds the reason ID, PIN_REASON_ID_MBI_DISTRIBUTION_REQD to the PIN_FLD_PAYMENT_REASONS array in the output flist. This reason ID helps in later payment processing by distinguishing a normal payment from an account payment made to an account with multiple bill units.

If the payment fails the validation, BRM informs you that the payment cannot be posted. For example, if a payment specifies no account number and no bill number, BRM cannot post the payment. You must create an exception batch to handle payments that fall into this category.

About the Default Payment Validation Process

PCM_OP_PYMT_POL_VALIDATE_PAYMENT enables you to customize how to validate payments to determine whether they can be successfully posted or whether a failed, unconfirmed payment needs reversal.

This opcode also identifies if the account payment is made to accounts with multiple bill units. During validation, this opcode tries to find any missing data needed to process payments. If automatic write-off reversals are enabled, this opcode also determines whether BRM should perform a write-off reversal.

PCM_OP_PYMT_POL_VALIDATE_PAYMENT opcode processes payments in three phases:

  1. Payment suspense phase: Receives a list of payments from PCM_OP_PYMT_VALIDATE_PAYMENT and checks the /config/business_params object to determine whether Payment Suspense Manager is enabled. If so, it checks the payments to determine whether any payments must be suspended and updates the PIN_FLD_STATUS field accordingly.

  2. Failed unconfirmed payment phase: For all payments with a PIN_FLD_STATUS in the failed range, uses the payment method value to determine whether a failed payment has an associated unconfirmed successful payment or if it is a failed confirmed payment.

    The input flist contains the POID of the original payment item, the transaction ID, and the amount of the original payment to properly handle unconfirmed failed payments.

  3. Write-off reversal phase: Checks the /config/business_params object to determine whether automatic write-off reversals are enabled. If so, it determines whether the payment is for an account, bill, or bill item that has been written off. If so, it sets PIN_FLD_STATUS accordingly.

Payment Suspense Phase

In this phase, PCM_OP_PYMT_POL_VALIDATE_PAYMENT first checks the PIN_FLD_STATUS field to determine whether the payment has a status in the suspense range, indicating that the payment has already been marked for suspense. In this case, the opcode passes the output flist and associated status back to PCM_OP_PYMT_VALIDATE_PAYMENT. BRM will then use PCM_OP_PYMT_COLLECT to direct the payment to the payment suspense account.

If the payment is not already marked for suspense, PCM_OP_PYMT_POL_VALIDATE_PAYMENT does the following:

  1. Validates the account number specified by the PIN_FLD_ACCOUNT_NO or PIN_FLD_ACCOUNT_OBJ field in the input flist or searches for the corresponding account POID.

  2. Validates the bill number specified by the PIN_FLD_BILL_NO field in the input flist and searches for the corresponding bill POID, bill unit POID, and account POID.

  3. If neither a bill POID nor a bill number was submitted with the payment, BRM uses the bill amount to find the bill.

    If the account and bill numbers supplied in the input flist are both invalid or PCM_OP_PYMT_POL_VALIDATE_PAYMENT cannot find the account or bill POIDs (or bill amount), it marks the payment for suspense. It also compares the account POID from the /bill object with the account POID found in step 1. If they do not match, the opcode marks the payment for suspense.

  4. Checks the PIN_FLD_STATUS field in the /account object to determine whether the account is closed. If the account is closed, PCM_OP_PYMT_POL_VALIDATE_PAYMENT marks the payment for suspense.

  5. Checks any custom validation criteria and marks the payment for suspense if appropriate.

  6. Writes the status of the payment in the PIN_FLD_STATUS field, and includes this field in the output flist. If the payment must be suspended, it sets this field to one of the values in the suspense range, as appropriate.

    Note:

    • When an /event/billing object is created for a suspended payment, it stores the original reason code associated with a failed payment that has been flagged for suspense. This ensures that the reason initially associated with the failed payment is not lost if BRM places the payment in suspense.

    • When the /event/billing/payment object is created, it stores the original account number provided for the payment being suspended, the original bill number, and the original transaction ID.

Failed Unconfirmed Payments Phase

In this phase, the opcode considers only payments whose status is marked as failed: those whose PIN_FLD_STATUS value is in the financially failed range. These payments are ones that the opcode was able to validate, but were marked by the payment processor as failing for financial reasons. In default implementations, the opcode requires the transaction ID and result of each payment to prepare the failed unconfirmed payments for reversal.

If the failed payment is an unconfirmed payment, PCM_OP_PYMT_VALIDATE_PAYMENT:

  1. Searches the /event/billing/payment object for an unconfirmed payment with the transaction ID passed in with the failed payment.

  2. Does one of the following:

    • If an unconfirmed payment is found, sets PIN_FLD_RESULT to PIN_PAY_TYPE_SUCCESS.

    • If the transaction ID of the unconfirmed payment is not found, it checks the /config/business_params object to determine whether Payment Suspense Manager is enabled.

      If so, it sets PIN_FLD_STATUS to PIN_FLD_FAILED_SUSPENSE and BRM posts the payment to the payment suspense account.

      If not, it sets PIN_FLD_RESULT to PIN_FLD_PAYMENT_RESULT_FAIL, and a reversal does not occur. The subsequent steps do not occur and manual allocation is required.

  3. Loads the following unconfirmed payment information from the /event/billing/payment storable class into the PIN_FLD_FAILED_PAYMENT_FEE substruct in the PIN_FLD_EXTENDED_INFO substruct of the output flist:

    • Payment channel ID

    • Payment method

    • Transaction ID

    • Original payment amount

    • Customer segment

      Note:

      For unconfirmed payments, the customer segment value is also retrieved from PIN_FLIST_CUSTOMER_SEGMENT_LIST in the input flist of this policy.

  4. Passes the POID of the successful unconfirmed payment in the output flist to PCM_OP_BILL_REVERSE_PAYMENT so it can be reversed.

The output flist sends the array of reversal events and tax events (if created) that were passed in by PCM_OP_AR_WRITEOFF_REVERSAL.

Write-off Reversal Phase

In this phase, PCM_OP_PYMT_VALIDATE_PAYMENT considers only payments whose status is marked as successful: those whose PIN_FLD_STATUS value is in the successful range. The opcode determines which of these payments is for an account, bill, or bill item that has been written off. It performs the following operations:

  • Checks the /config/business_params object to determine if automatic write-off reversal functionality for payment processing is enabled.

  • If this is enabled, checks the /profile/writeoff object to verify that the write-off flag is set for the account.

  • If both checks are successful, sets the PIN_FLD_STATUS field in the output flist to PIN_PYMT_WRITEOFF_SUCCESS.

About Payment Validation Flags

Flags are not used directly by PCM_OP_PYMT_POL_VALIDATE_PAYMENT. They are passed in from PCM_OP_PYMT_COLLECT for PCM_OP_PYMT_SELECT_ITEMS. For example, Payment Tool can set the PCM_BILLFLG_DEFER_ALLOCATION flag to indicate which payments should be left unallocated.

Configuring Unconfirmed Payment Processing

BRM requires acknowledgment from a bank or payment processor before posting BRM-initiated payments. In some cases, the response from the bank or payment processor does not occur immediately with the request for funds. In that case, you can allow BRM to post unconfirmed payments.

To avoid the possible delay in posting payments, you can configure a new payment Data Manager (DM) to post payments immediately, before the funds are confirmed by the bank or payment processor. The DM requires an input flist of payments from BRM and must return the results to BRM in the output flist.

If the payment processor later sends a failure notification (for example, due to insufficient funds or an expired credit card), BRM reverses the initially successful payments and posts the failed payments.

Note:

Only credit card and debit card payment methods can be posted before they are confirmed.

If the bank or payment processor later sends a failure notification for a BRM-initiated payment (for example, due to insufficient funds or an expired credit card), BRM reverses the initially-successful payments and posts the failed payments.

Failed unconfirmed payments can be submitted to BRM by using a payment gateway, or by using Payment Tool or another third-party payment application.

Failed unconfirmed payments are recorded as /event/billing/payment/failed events, and the reversals of the initially-successful payments are recorded as /event/billing/reverse/pay_type events.

When a unconfirmed payment fails, the failed payment is recorded in BRM with a balance impact of 0, and the successful payment amount is re-applied to the account balance.

Failed unconfirmed payments are processed by the PCM_OP_PYMT_COLLECT opcode. The interface you use to load failed payments into the BRM database must be configured to send the following information with each failed payment to be validated in BRM:

  • Transaction ID

  • Failed payment status

  • Failure reason ID

The transaction ID of the failed payment is compared against the transaction ID in the /event/billing/payment/pay_type object of the initial unconfirmed payment that was posted successfully in BRM.

If the transaction IDs are the same, the original payment is reversed and the failed payment is recorded. If the transaction ID is missing or incorrect, or the successful payment cannot be located in the database, the PCM_OP_PYMT_VALIDATE_PAYMENT opcode returns a value of PIN_PYMT_FAILED in the PIN_FLD_RESULT field, and an error is displayed. The payment is not reversed and the failed payment is not allocated. You must manually fix the transaction ID to resubmit the payment. Or, you can configure BRM to identify the original payment by using other payment attributes. See BRM Opcode Guide.

When a failed unconfirmed payment is received, the original successful payment is identified by using its transaction ID.

The PIN_FLD_PAYMENT_TRANS_ID field in the /event/billing/payment/failed event must be equal to the PIN_FLD_TRANS_ID of the successful unconfirmed payment item. If so, the unconfirmed payment is reversed and the failed payment posted to the proper account.

If the payment processor is not able to send a transaction ID with each payment, or if the transaction ID is not a reliable means of identifying a payment, you can configure PCM_OP_PYMT_POL_VALIDATE_PAYMENT to find the original unconfirmed payment by using other payment properties. For example, you can use a combination of the payment amount, account number, and invoice number.

When the payment is received, BRM compares these values in the failed payment with those of the original unconfirmed payment, and if the values match, it will reverse the unconfirmed payment and post the failed payment.

Note:

The result of the validation is the POID of the unconfirmed successful payment item that was recorded in BRM. If the item is not available, the reversal cannot occur. By default, this policy opcode retrieves the item by finding the payment event with corresponding transaction ID.

Handling Overpayments and Underpayments

If a customer pays too much or too little, your Oracle Communications Billing and Revenue Management (BRM) business policies may require payment allocation.

  • For underpayments, choose which bills or items to allocate the payment to.

  • For overpayments, pay all items and generate a credit balance.

By default, BRM requires overpayments to be allocated.

To change the default BRM behavior for overpayments and underpayments, customize the PCM_OP_PYMT_POL_UNDER_PAYMENT or PCM_OP_PYMT_POL_OVER_PAYMENT policy opcodes.

If the money received is more or less than the sum of the total due of all the open items selected by PCM_OP_PYMT_SELECT_ITEMS, PCM_OP_PYMT_SELECT_ITEMS calls PCM_OP_PYMT_POL_OVER_PAYMENT or PCM_OP_PYMT_POL_UNDER_PAYMENT, respectively. PCM_OP_PYMT_SELECT_ITEMS does not call these policy opcodes if:

  • The amount is equal to the sum of the total due.

  • The flag PIN_BILLFLG_SELECT_FINAL is passed in.

  • The flag PIN_BILLFLG_DEFER_ALLOCATION is passed in.

By default, PCM_OP_PYMT_POL_OVER_PAYMENT returns the amount overpaid on the output flist. The excess amount remains in the bill unit (/billinfo object) specified on the input flist (or the default bill unit if none was specified) until they are manually redistributed by using Billing Care or Customer Center. You can customize PCM_OP_PYMT_POL_OVER_PAYMENT to perform as a hook for an application that would search for and settle all overpaid payment items.

By default, PCM_OP_PYMT_POL_UNDER_PAYMENT pays the billed items in the order they are listed on the input flist (item[0] first, then item[1], item [2], and so on). It then returns the items paid on the output flist. Items that are partially paid are returned with a new amount due. Items not paid are not returned.

Calculating Payment Collection Dates

By default, BRM-initiated payments, such as payments made by credit card or direct debit, are collected on the date that bills are finalized. Alternatively, you can configure BRM to collect a BRM-initiated payment on the date a bill is due or on a specified number of days before the bill is due.

To support configurable payment collection dates, PCM_OP_BILL_POL_CALC_PYMT_DUE_T calculates a bill's payment collection date after calculating its due date.

Note:

Although configurable payment collection dates are used only for BRM-initiated payments, they are calculated and stored for bills associated with all payment methods.

To calculate payment collection dates, PCM_OP_BILL_POL_CALC_PYMT_DUE_T performs these tasks:

  1. Finds the /payinfo object that is linked to the bill unit with which the bill is associated.

  2. Reads the value of the PIN_FLD_PAYMENT_OFFSET field in the /payinfo object.

  3. Does one of the following:

    • If the value is -1, sets the payment collection date to the date the bill is finalized.

    • If the value is 0, sets the payment collection date to the date the bill is due.

    • If the value is any positive integer (x), sets the payment collection date to x days before the bill is due.

      Note:

      If x makes the payment collection date earlier than the date the bill is finalized, PCM_OP_BILL_POL_CALC_PYMT_DUE_T uses the finalization date instead.

  4. Stores the payment collection date in the PIN_FLD_COLLECTION_DATE field of the /billinfo object.

    Note:

    By default, the pin_collect utility collects BRM-initiated payments for all bills associated with /billinfo objects whose PIN_FLD_COLLECTION_DATE is the day the utility is run or the day before the utility is run.

How BRM Selects the Items to Which Payments Are Applied

PCM_OP_PYMT_COLLECT calls PCM_OP_PYMT_SELECT_ITEMS to identify the items to which the payment is applied. PCM_OP_PYMT_SELECT_ITEMS is also called by Payment Tool.

When an account payment is made to an account having multiple bill units, this opcode processes more than one bill unit to get the item distribution corresponding to each bill unit.

In case of overpayment to an account, PCM_OP_PYMT_SELECT_ITEMS contains more than two PIN_FLD_BILLINFO arrays for the default bill unit. PCM_OP_PYMT_SELECT_ITEMS does not perform an item distribution for the second PIN_FLD_BILLINFO array for the default bill unit and sets the select status as PIN_SELECT_STATUS_OVER_PAYMENT. This restriction prevents the opcode from doing item distribution twice in two different PIN_FLD_BILLINFO arrays.

PCM_OP_PYMT_SELECT_ITEMS does the following:

  1. Selects open items based on the input fields and the accounting type of the account..

  2. If the amount passed in on the input flist is not in the primary account currency, PCM_OP_PYMT_SELECT_ITEMS attempts to convert it to the primary account currency.

  3. One of the following actions is taken:

    • If called by PCM_OP_PYMT_COLLECT, PCM_OP_PYMT_SELECT_ITEMS returns the PIN_FLD_AMOUNT and the list of selected items.

    • If called by Payment Tool, PCM_OP_PYMT_SELECT_ITEMS compares the sum of the amount due from all the selected items to the PIN_FLD_AMOUNT value to see if the payment is an exact payment, an overpayment, or an underpayment.

      If it is an overpayment, it calls PCM_OP_PYMT_POL_OVER_PAYMENT. By default, PCM_OP_PYMT_POL_OVER_PAYMENT returns the amount overpaid on the output flist. Excess monies remains in the payment item until they are manually redistributed with Payment Tool.

      If it is an underpayment, it calls PCM_OP_PYMT_POL_UNDER_PAYMENT.

      By default, PCM_OP_PYMT_POL_UNDER_PAYMENT pays the billed items in the order they are listed on the input flist (item[0] first, then item[1], item [2], etc.). It then returns the items paid on the output flist. Items that are partially paid are returned with a new amount due. Items not paid are not returned.

  4. Returns the list of selected items.

Items are selected by PCM_OP_PYMT_SELECT_ITEMS based on the fields in the input flist.

  • The contents of the PIN_FLD_BILLS array is examined. For BRM-initiated payments, the contents of the PIN_FLD_BILLINFO array is also examined.

    • The PIN_FLD_BILLS array indicates which /bill object PCM_OP_PYMT_SELECT_ITEMS is collecting or paying off. If one or more bills are included, all items belonging to those bills are selected. If none is specified, the default bill unit is used to apply the payment.

    • The PIN_FLD_BILLINFO array specifies the bill unit to select items for. If none is specified, the items are retrieved based on the bills in the PIN_FLD_BILLS array. If neither a bill unit POID nor a bill is included, the items are selected from the account's default bill unit. This is the bill unit that contains the default balance group for the account.

      Note:

      For account payments to accounts with multiple bill units, there are multiple PIN_FLD_BILLINFO arrays corresponding to each bill unit that contains the bill unit–level distribution.

  • If the accounting type is PIN_ACTG_TYPE_OPEN_ITEMS or if the accounting type is PIN_FLD_ACTG_TYPE_BALANCE_FORWARD and the PIN_FLD_BILLS array is passed in, there are two options for items to be eligible for the selection criteria:

    • If the PIN_FLD_INCLUDE_CHILDREN field is not specified or is specified and set to 1, items that belong to the A/R bill unit (including nonpaying child bill items) are selected.

    • If the PIN_FLD_INCLUDE_CHILDREN field is specified and set to 0, items that belong only to the specified bill are selected.

      Note:

      PIN_FLD_INCLUDE_CHILDREN applies only when the PIN_FLD_BILLS array is specified.

  • If PIN_FLD_ACTG_TYPE is PIN_FLD_ACTG_TYPE_BALANCE_FORWARD and PIN_FLD_BILLS is not specified, PCM_OP_PYMT_SELECT_ITEMS selects all the open items for this bill unit and sums up the amount due from all the open items selected.

  • The PIN_FLD_AMOUNT field determines whether the overpayment or underpayment policy opcodes are called. If PIN_FLD_AMOUNT is not specified, the payment amount is based on the charges of the bill unit's open items.

    If the PIN_FLD_AMOUNT field is passed:

    • The payment is not allocated to other open items and the deferred allocation flag is set.

    • The payment must be allocated manually.

  • If the PIN_FLD_BILLINFO array contains bill unit level payment distribution, PCM_OP_PYMT_SELECT_ITEMS finds out the item distribution for the selected bill units.

Allocating Account Payments to Multiple Bill Units

If an account payment is made to an account having multiple bill units, you can allocate the payment to multiple bill units of the account.

Note:

The Payment Suspense Management feature must be enabled in your BRM system for you to allocate account payments to multiple bill units.

To allocate an account payment to multiple bill units of an account, BRM calls PCM_OP_PYMT_COLLECT. PCM_OP_PYMT_COLLECT performs the following operations:

  1. Opens a transaction.

  2. Calls PCM_OP_PYMT_VALIDATE_PAYMENT to validate the payment.

    PCM_OP_PYMT_VALIDATE_PAYMENT invokes PCM_OP_PYMT_POL_VALIDATE_PAYMENT to validate the payment. This opcode:

    1. Checks the appropriate /config/business_params objects to find out if Payment Suspense Manager is enabled.

    2. Checks that the payment is an account payment and that the account has multiple bill units.

    3. If the payment is successful and passes the validation process, adds the reason ID, PIN_REASON_ID_MBI_DISTRIBUTION_REQD to the PIN_FLD_PAYMENT_REASONS array in the output flist.

      Note:

      For failed or suspended payments, PCM_OP_PYMT_POL_VALIDATE_PAYMENT does not add the PIN_REASON_ID_MBI_DISTRIBUTION_REQD reason ID.

  3. Calls PCM_OP_PYMT_MBI_DISTRIBUTE to distribute the payment to multiple bill units. PCM_OP_PYMT_MBI_DISTRIBUTE invokes PCM_OP_PYMT_POL_MBI_DISTRIBUTE if the following conditions are true:

    • PCM_OP_PYMT_POL_VALIDATE_PAYMENT returns the PIN_REASON_ID_MBI_DISTRIBUTION_REQD reason ID.

    • The PIN_FLD_SELECT_STATUS field in the PCM_OP_PYMT_COLLECT input flist is not PIN_SELECT_STATUS_MBI_DISTRUBUTED.

    Payment Tool calls PCM_OP_PYMT_MBI_ITEM_SEARCH to retrieve the bills/item across multiple bill units of the account. You can override the default distribution by manually allocating the payment. After manual allocation of payment, revalidate the payment.

    PCM_OP_PYMT_MBI_ITEM_SEARCH gets all the items of the bill units in a tree view. The bills are displayed under their corresponding bill units, and the items for a bill are displayed under their corresponding bill.This opcode is called by Payment Tool only while manually allocating the payment.This opcode calls PCM_OP_PYMT_ITEM_SEARCH.

    PCM_OP_PYMT_POL_MBI_DISTRIBUTE distributes the payment according to the default distribution logic. You can customize how payments are distributed by using PCM_OP_PYMT_POL_MBI_DISTRIBUTE. This opcode searches for all the open /bill objects of all the /billinfo objects of the specified /account object, sorted by the bill due date.

    PCM_OP_PYMT_POL_MBI_DISTRIBUTE returns the PIN_FLD_BILLINFO array that contains an array of PIN_FLD_BILLS having the distributed payment amount for each bill. The PIN_FLD_BILLINFO array is added to the PCM_OP_PYMT_MBI_DISTRIBUTE output flist, which is passed to PCM_OP_PYMT_SELECT_ITEMS to get item distribution.

  4. Calls PCM_OP_PYMT_SELECT_ITEMS for item payment distribution for each bill unit.

  5. If the reason ID in the PCM_OP_PYMT_SELECT_ITEMS output flist is PIN_REASON_ID_MBI_DISTRIBUTION_REQD, PCM_OP_PYMT_COLLECT detaches the distribution part from the output flist to use later while recycling payment.

  6. If the reason ID in the PCM_OP_PYMT_SELECT_ITEMS output flist is PIN_REASON_ID_MBI_DISTRIBUTION_REQD and the PIN_FLD_STATUS value is successful (value in the range of 0 to 14), PCM_OP_PYMT_COLLECT changes the status to PIN_PYMT_SUSPENSE to suspend the payment before calling PCM_OP_PYMT_POL_PRE_COLLECT.

  7. Calls PCM_OP_PYMT_POL_PRE_COLLECT to perform policy checks before the payment occurs.

  8. Calls PCM_OP_PYMT_POL_SUSPEND_PAYMENT to get the suspense account.

  9. Calls PCM_OP_BILL_RCV_PAYMENT to record the payment and create the payment item.

  10. Prepares the PCM_OP_PYMT_RECYCLE_PAYMENT input flist by using the distribution detached from PCM_OP_PYMT_SELECT_ITEMS.

  11. Calls PCM_OP_PYMT_RECYCLE_PAYMENT to distribute the suspended payment to multiple bill units.

  12. Prepares the PCM_OP_PYMT_COLLECT output flist such that the output flist contains all the payment events created as a result of the recycle payment.

Default payment distribution follows these rules:

  • Bills having older due dates receive the payment amount first.

  • If all bills have the same due date, the bills with the higher due amounts are considered first for payment distribution.

  • In case of overpayment, the excess payment amount remains unallocated to the default bill unit of the account.

  • In case of underpayment, bills with later due dates or low due amounts do not get any payment amount.

  • For hierarchical accounts, the bills for the parent are considered first.

    Note:

    By default, PCM_OP_PYMT_POL_MBI_DISTRIBUTE provides bill distribution. So, BRM considers only the open bill items for payment distribution. However, you can update this opcode to return bill-unit payment distribution. If bill-unit distribution is passed to PCM_OP_PYMT_SELECT_ITEMS, payment considers all the open items, even if an open item is a bill item or an A/R item.

Allocating Externally Initiated Payments by Due Amount

When allocating an externally initiated payment, such as a payment made by check or cash, that is associated with a valid account number but not a valid bill POID, BRM uses PCM_OP_PYMT_POL_VALIDATE_PAYMENT to find the appropriate bill as follows:

  1. If the element associated with the payment in the PIN_FLD_CHARGES array of PCM_OP_PYMT_POL_VALIDATE_PAYMENT input flist has a bills array (PIN_FLD_BILLS) and the array contains a bill number (PIN_FLD_BILL_NO), the opcode searches for the bill POID associated with the bill number.

  2. If PCM_OP_PYMT_POL_VALIDATE_PAYMENT finds the POID, it adds it to the bills array in its output flist. The information in the output flist is passed to PCM_OP_PYMT_SELECT_ITEMS by Payment Tool or by PCM_OP_PYMT_COLLECT.

  3. If the payment is not associated with a valid bill number, the opcode searches for a bill whose total due amount matches the payment amount. The search is restricted to bills linked to the account with which the payment is associated.

    Note:

    By default, this search is disabled.

Reversing Payments

Payments are directly reversed from BRM by using Payment Tool.

Note:

To reverse payments, PCM_OP_BILL_REVERSE calls PCM_OP_BILL_REVERSE_PAYMENT. PCM_OP_BILL_REVERSE is the recommended opcode to use. It is a wrapper for PCM_OP_BILL_REVERSE_PAYMENT. Custom client applications should not directly call PCM_OP_BILL_REVERSE_PAYMENT.

To process a payment reversal batch, PCM_OP_BILL_REVERSE performs the following operations:

  1. Opens a transaction and checks the appropriate /config/business_params objects to find out if Payment Suspense Manager is enabled.

  2. Validates that the PIN_FLD_FLAGS field is not present in the input flist or, if the flag is present, that it is not set to PIN_REVERSE_FLAG_REVERSE_AS_UNALLOCATED (1). If the flag is set, the operation fails because payments that were removed already from BRM as unallocatable cannot also be reversed.

  3. Checks the PIN_FLD_STATUS field of each reversal associated with the payment being reversed.

  4. Calls PCM_OP_PYMT_RECYCLED_PAYMENTS_SEARCH, which performs the following operations:

    • Validates that the payment does not have a SUB_TRANS_ID value, and is therefore the original payment. If the payment has a SUB_TRANS_ID value, the operation will fail.

    • Finds all distributed payment events that have the same SUB_TRANS_ID value as this payment's TRANS_ID value, and have not been reversed already due to the recycling process.

    • Assigns a reversal TRANS_ID value to each payment returned by the search and populates the reversal flist with each TRANS_ID value.

  5. Checks the PIN_FLD_STATUS field of each /event/billing/reversal object associated with the payment being reversed to ensure that no part of the payment has been removed from suspense as unallocatable.

  6. Calls PCM_OP_BILL_REVERSE_PAYMENT to reverse the list of payments.

    • If the payment was originally made to a customer account, the list includes any recycled payment generated if the payment was moved into the suspense account after it posted to the customer account.

    • If the payment was originally made to the suspense account, the list contains all payments generated from the original payment, including distributed payments and any payment remaining in the suspense account.

      When performing reversals during payment suspense recycling, PCM_OP_BILL_REVERSE_PAYMENT must be called by PCM_OP_PYMT_RECYCLE_PAYMENT to ensure that only payments with a SUB_TRANS_ID value of NULL can be reversed directly. The reversal of recycled payments is disallowed if the reversal is not called by PCM_OP_PYMT_RECYCLE_PAYMENT. Only suspended payments and payments in customer accounts which have not been recycled can be reversed directly by PCM_OP_BILL_REVERSE_PAYMENT.

    • If the reversal is called for a SEPA payment transaction, the opcode creates the /sepa/dd/reversal object only if the original payment request is in the REQUESTED status. If the charge event, /event/billing/charge/sepa, does not exist, it records the reversal only (the /sepa/dd/reversal object is not created assuming that the payment request has not been sent to the bank).

    The sum of all the payments reversed in this operation should equal the amount of the original payment.

    PCM_OP_BILL_REVERSE_PAYMENT verifies that the reversal operation was successful for all of the payments. It uses the PIN_FLD_SESSION_OBJ field in the input flist to reference the reversal batch event.

    It also checks the /config/business_params object to determine whether payment incentives are enabled. If so, PCM_OP_BILL_REVERSE_PAYMENT calls PCM_OP_PYMT_REVERSE_INCENTIVE, which removes the payment incentive trigger in the bill unit, thus eliminating the payment incentive.

  7. Populates the payment batch with the sum of the reversal flist.

  8. Returns the reversal information for all the payments in the PIN_FLD_MULTI_RESULTS array.

The PIN_FLD_RESULTS field of the output flist indicates whether the reversal was successful. Direct reversal is not allowed if either of the following conditions is true:

  • The payment has a SUB_TRANS_ID value and, therefore, is not an original payment.

  • PCM_OP_BILL_REVERSE is called from PCM_OP_PYMT_RECYCLE_PAYMENT. In this case, a reversal takes place, but it is not a direct reversal. See "How Suspended Payments Are Reversed".

To reverse account-level payment made to an account having multiple bill units, you pass the original payment's transaction ID to Payment Tool. When you submit a reversal batch, the reversal batch reverses all the sub-payments created during the account-level payment allocation to multiple bill units.

To customize how written off payments are reversed, use PCM_OP_BILL_POL_REVERSE_PAYMENT.

If you have Payment Suspense Manager enabled, you can reverse only original payments. For information on payment reversals that occur during payment suspense processing, see "How Suspended Payments Are Reversed".

Refunding Payments

PCM_OP_BILL_ITEM_REFUND is used to create a refund item for a bill or bill unit. POIDs passed in to either the PIN_FLD_BILL_OBJ field or the PIN_FLD_BILLINFO_OBJ field specify the billing entity to receive the refund.

After the refund items are created, BRM uses PCM_OP_PYMT_COLLECT to refund the payment amount to the account. For BRM-initiated payments, use the pin_collect utility to refund payments based on the payment method. For externally initiated payments, use Billing Care or Customer Center to perform the refund operation.

Before it refunds a payment, BRM determines whether Payment Suspense Manager is enabled. If so, it checks the account POID in the input flist against the account POID in the /config/psm object to see whether the account is the suspense account. If the two POIDs match, the opcode generates an error.

There are two ways to run PCM_OP_BILL_ITEM_REFUND: calculate-only mode or regular mode.

In calculate-only mode, PCM_OP_BILL_ITEM_REFUND:

  • Computes the total refund amount without actually creating the refund item or committing any changes to the database.

  • It shows the amount that a CSR can refund, based on both credit and debit items.

In the regular mode, PCM_OP_BILL_ITEM_REFUND does the following:

  • Creates a refund item for the account if it has an open credit. Otherwise the refund fails and an error message is returned.

  • Transfers amounts from any open credit items to the new refund item, and closes the credit items.

    Note:

    For any transfers, PCM_OP_BILL_ITEM_REFUND calls PCM_OP_BILL_ITEM_TRANSFER.

  • Transfers amounts from the bill unit or bill to any open debit items.

    Each transfer from the new refund item to debit items decreases the value of the new refund item.

  • Creates the /item/refund object, which contains the total credit amount.

  • Closes these credit and debit items.

  • Returns the refundable amount in the /item/refund object.

If you use a custom program to perform refunds, you can put the program name in the input flist optional field PIN_FLD_PROGRAM_NAME. If this field is used to contain the name of the program refunding a customer's account, the program name is recorded in the events associated with an item refund. If the program name is not specified, the default value, Refund Opcode, is used.

Note:

  • You cannot refund suspended payments.

  • You cannot reverse a refund. If you refund a customer's account by mistake, adjust the account for the refunded amount.

Finding Payment Info

To find /payinfo objects that belong to an account, use PCM_OP_CUST_FIND_PAYINFO.

This opcode is given the account POID and returns the information from the storable /payinfo object.

Adding a Custom Payment Method

To add a payment method:

  • Update the /config/payment object.

  • Modify the PCM_OP_CUST_POL_PREP_PAYINFO policy opcode to validate the custom payment method. For example, add code for your custom payment method everywhere the opcode checks the various payment methods.

To add a custom payment method:

  1. Using a text editor, edit the PCM_OP_CUST_POL_PREP_PAYINFO policy opcode source code to add an element to the PIN_FLD_PAY_TYPES array for each new payment method.

    • For a predefined payment method, use the appropriate value as the index for that element of the PIN_FLD_PAY_TYPES array.

    • For a custom payment method, define a payment method in a header file and use that value as the index of the new element in the PIN_FLD_PAY_TYPES array.

      Note:

      To avoid conflicts with payment IDs used by BRM, define custom payment methods with an element ID of 10100 or higher.

  2. Save and close the file.

  3. Use the testnap utility to load the /config/payment object into the database. See "Testing Your Applications and Custom Modules" in BRM Developer's Guide.

Creating a /config/payment Object

Instead of changing the default /config/payment object, you can configure your own /config/payment object and load it into the database using the testnap utility. See BRM Developer's Guide.

After you create the /config/payment object, update the config_payment entry in the CM pin.conf file with the POID of the new object:

  1. Open the CM configuration file (BRM_home/sys/cm/pin.conf).

  2. Edit the following entry:

    - fm_pymt config_payment database_number /config/payment 200
    

    where database_number is the database number of the BRM database. By default, this number is 0.0.0.1. Replace 200, the default POID of the /config/payment object, with the POID of the new object.

  3. Save and close the file.

  4. Stop and restart the CM.

Viewing Payment Information for a Custom Payment Method

To view payment information for custom payment methods, run the pin_collect utility for that payment method. The pin_bill_day utility calls pin_collect for credit card payment methods and pin_inv_accts for invoice payment methods. You can make a call to pin_collect in pin_bill_day for each new custom payment method.

For more information, see BRM Configuring and Running Billing guide and BRM Configuring and Collecting Payments guide.

Configuring Payment Center for Custom Payment Methods

If you create custom payment methods for your BRM system, you must customize Payment Center to handle them. This overview procedure describes how to create custom storable classes and fields and enable Payment Center to handle them.

Note:

Before customizing your payment functionality, you should be familiar with the Java PCM and the BRM Storable Class Editor, which you use to create custom storable classes and fields. For background information on creating custom storable classes and fields, see "Creating Client Applications by Using Java PCM" and "Creating Custom Fields and Storable Classes" in BRM Developer's Guide.

  1. Complete the following tasks by using Storable Class Editor:

    1. Create your storable classes and fields in the Java PCM package.

    2. Create source files for your custom fields.

      Note:

      Storable Class Editor creates a C header file called cust_flds.h, a Java properties file called InfranetPropertiesAdditions.properties, and a Java source file for each custom field.

  2. In the directory in which Storable Class Editor created the Java source files, compile the source files:

    javac -d . *.java
    
  3. Package the new storable class files into a JAR file. For example:

    jar cvf customfields.jar *.class
    
  4. Copy the contents of the InfranetPropertiesAdditions.properties file and paste it into the Payment Center Infranet.properties file. By default, this file is located in the C:\Program Files\Portal Software\PaymentCtr\PaymentCenter directory.

  5. Append the location of the JAR file to the PAYCTRCP environment variable path. For example:

    ;.;C:\Program Files\Portal Software\PaymentCtr\customfields.jar;

How Opcodes Read the Payment Method

Payment methods are used in the following objects:

  • The PIN_FLD_PAY_TYPE field in the /billinfo object defines the payment method for an account's bill. All defined payment methods are stored in the /config/payment object.

  • When you add a new payment method to your BRM system, you must update the PIN_FLD_PAY_TYPES array in the /config/payment object. The PIN_FLD_PAY_TYPES array index corresponds to an entry in the pin_pymt.h file, where payment methods are defined.

When you create a payment method, you must consider the opcodes that might use that payment method. For example, if you change a customer's payment method to a custom payment type, you must add the new payment method, when first used, to the input flist of the opcodes that use the PIN_FLD_PAY_TYPE field. This is required if an invoice customer makes a one-time payment by using a new credit card. If the new payment method is SEPA, you must add the payment method to the account before it can be used. This is not required if the payment method was defined when the account was created.

The following lists the opcodes that use the PIN_FLD_PAY_TYPE field:

  • PCM_OP_PYMT_CHARGE

  • PCM_OP_PYMT_CHARGE_CC

  • PCM_OP_PYMT_COLLECT

  • PCM_OP_BILL_GROUP_DELETE_MEMBER

  • PCM_OP_BILL_MAKE_BILL

  • PCM_OP_BILL_MAKE_BILL_NEW

  • PCM_OP_BILL_MAKE_BILL_ON_DEMAND

  • PCM_OP_BILL_MAKE_BILL_RCV_PAYMENT

  • PCM_OP_PYMT_RECOVER

  • PCM_OP_BILL_REVERSE

  • PCM_OP_BILL_REVERSE_PAYMENT

  • PCM_OP_PYMT_VALIDATE

When you define a custom payment method, you must provide information about the payment method. Table 20-9 lists the fields in PIN_FLD_PAY_TYPES array.

Table 20-9 Fields in PIN_FLD_PAY_TYPE

Field name Description

PIN_FLD_PAYINFO_TYPE

A string that indicates the type of /payinfo object to create.

PIN_FLD_PAYMENT_EVENT_TYPE

A string that indicates the type of /event object to create when payment is received.

PIN_FLD_REFUND_EVENT_TYPE

A string that indicates the type of /event object to create when a refund is paid.

PIN_FLD_OPCODES

An array that contains the following information about an opcode to be associated with this pay type:

  • PIN_FLD_NAME

    The name of the opcode to be associated with this pay type.

  • PIN_FLD_OPCODE

    The number of the opcode to be associated with this pay type.

  • PIN_FLD_EVENT_TYPE

    A string that indicates the type of /event object to create.

  • PIN_FLD_FLAGS

    Flags passed to opcodes when run.

Table 20-10 lists the PIN_FLD_OPCODES array indexes-to-opcode mapping.

Table 20-10 Index to Code Mapping for PIN_FLD_OPCODES

Value/Element ID Opcode type

0

PIN_PAY_VALIDATE

1

PIN_PAY_CHARGE

2

PIN_PAY_RECOVER

3

PIN_BILL_REVERSAL

Processing Payment Fees

When processing payment fees:

Applying Payment Fees

Payment fees are applied by PCM_OP_PYMT_APPLY_FEE. This opcode creates payment fees for payments that fail, for example, due to insufficient account funds or an expired credit card. It calls PCM_OP_ACT_USAGE to create the payment fee event to be rated.

When a failed payment is posted in BRM, it is recorded in BRM with a balance impact of 0, and is identified by a transaction ID, a failure status, and a reason ID for the failure. BRM uses the failure status and reason ID to determine whether to apply payment fees when the payment is posted. Payment fees can be applied only to payments that have a PIN_FLD_STATUS value of PIN_PYMT_FAILED in the /event/billing/payment/failed object.

PCM_OP_PYMT_APPLY_FEE is called by PCM_OP_PYMT_COLLECT.

The behavior of PCM_OP_PYMT_APPLY_FEE is determined by the PIN_FLD_STATUS field passed in on the input flist. Payments are eligible to receive payment fees if they have a PIN_FLD_STATUS value >= PIN_PYMT_FAILED and < PIN_PYMT_STATUS_MAX. The numeric range for financially failed payments is 30-44.

The normal flow of PCM_OP_PYMT_APPLY_FEE is as follows:

  1. Checks the input flist for the status of the payment and the reason ID that describes why the payment failed.

  2. Calls PCM_OP_PYMT_POL_APPLY_FEE to perform custom checks before the failed payment fee is applied. See "Customizing Payment Fees".

    When it returns the output flist, PCM_OP_PYMT_APPLY_FEE validates the information, and creates the failed payment fee events for all failed payments based on the information. The default value in the PIN_FLD_BOOLEAN field on the output flist is 0, which specifies that the fee is created.

  3. If a payment fails, records the /event/billing/payment/payment_type event.

    Note:

    If the payment is an unconfirmed payment, records the /event/billing/payment/failed event.

  4. Creates the /event/billing/fee/failed_payment event.

PCM_OP_PYMT_APPLY_FEE provides feedback on its success or failure through the PIN_FLD_RESULTS array in the output flist. The value in the PIN_FLD_RESULTS field specifies whether the payment fee event was created. A value of 0 signifies that the payment fee event was created and the payment fee applied. A nonzero value signifies that the payment fee event was not created.

In the case of a write-off reversal, the output flist sends a results array of reversal events and tax events (if created) that were passed in by PCM_OP_AR_REVERSE_WRITEOFF.

Note:

Failed payments can only be applied to account numbers that already exist in the BRM database.

The PIN_FLD_EVENTS array of the output flist stores the POID of the failed payment fee event or write off event, if one is created. The PIN_FLD_EVENTS array is contained in the PIN_FLD_RESULTS array.

Flags are not used directly by PCM_OP_PYMT_APPLY_FEE. They are passed in from PCM_OP_PYMT_COLLECT for PCM_OP_PYMT_SELECT_ITEMS. For example, Payment Tool can set the PCM_BILLFLG_DEFER_ALLOCATION flag to indicate which payments should be left unallocated.

Customizing Payment Fees

You can define additional rules for payment fee processing by configuring PCM_OP_PYMT_POL_APPLY_FEE. This opcode is called by PCM_OP_PYMT_APPLY_FEE.

This opcode also enhances the /event/billing/fee/failed_payment object by providing additional fields that are recorded in the object.

PCM_OP_PYMT_POL_APPLY_FEE enables you to customize payment fees by preprocessing, filtering, and extending the information available in failed payment fee events. For example:

  • You can charge different fee amounts based on thresholds, or on the reason ID associated with a failed payment.

  • You can use payment attributes such as the customer segment, payment method, payment channel, or a combination of these attributes to charge payment fees. You create the filters by passing the values in the PIN_FLD_EXTENDED_INFO substruct or the PIN_FLD_CHARGES array.

The default behavior of PCM_OP_PYMT_POL_APPLY_FEE is determined by the PIN_FLD_STATUS and PIN_FLD_REASON_ID fields passed in on the input flist. It enhances the input flist by adding fields to filter and extend the information available in the payment fee events.

Note:

If the transaction ID, status or reason ID is missing from the actual payment, it can be retrieved from the payment batch header.

Using Custom Reason Codes to Customize Payment Fees

You can use custom reason codes to apply reasons to payment failures, and then customize payment fees based on those reasons.

To use custom reason codes, you mus customize the payment gateway to and your third-party payment application to identify failed payments and send reason codes with the payment information. When a failed payment is received, the reason code is mapped to the reason code ID defined in the BRM database.

You define reason codes in the reasons.locale file and load them into the BRM database as a /strings object. The file contains instructions on how to add the new domain Reason Codes - Payment Failure Reasons. For example:

DOMAIN = "Reason codes-Payment Failure Reasons";
STR
     ID = 1001 ;
     VERSION = 13 ;
     STRING = "Invalid Credit Card";
END

Note:

If you add your own reason codes to the reasons.locale file, you should use IDs above 100,000.

To define reason codes for failed payments, you edit the reasons.en_US sample file in the BRM_home/sys/msgs/reasoncodes directory. You then use the load_localized_strings utility to load the contents of the file into the /strings objects.

When you run the load_localized_strings utility, use this command:

load_localized_strings reasons.locale

Note:

  • If you are loading a localized version of this file, use the correct file extension for your locale. For a list of file extensions, see Locale names.

  • If a failed payment is loaded into BRM with an invalid reason code, payment fees are not applied.

For information on loading the reasons.locale file, see BRM Developer's Guide. For information on creating new strings for this file, see BRM Developer's Guide.

Customization example: Charging a fee based on the customer segment

The following opcode customization is used to control which failed payment fee is assigned to an account based on the account's customer segment:

If (customer_segment = “early bill payer")
Then set PIN_FLD_BOOLEAN to False
END

The PIN_FLD_BOOLEAN value of False specifies that the fee event is not created. When payments are posted, BRM uses the customer segment ID to determine if a payment fee is charged.

You can also use the PIN_RESULT_PASS and PIN_RESULT_FAIL return values in PCM_OP_PYMT_POL_APPLY_FEE to configure whether payment fees are applied.

Storing Additional Information with Payment Fees

You can store additional information for payment fees by extending the /event/billing/fee/failed_payment storable class. Use the PIN_FLD_FAILED_PAYMENT_FEE field inside the PIN_FLD_EXTENDED_INFO substruct. This enables you to record additional criteria you defined to create the payment fee.

You can then use the PIN_FLD_REASON_ID field in the input flist to configure fees based on this value of the PIN_FLD_FAILED_PAYMENT_FEE field. It contains the reason for failure that was sent by the payment processor for failed credit card and direct debit transactions.

You can then charge payment fees based on custom payment attributes such as currency type:

  1. Extend the /event/billing/fee/failed_payment storable class with the new attributes by using Developer Center.

  2. Customize PCM_OP_PYMT_POL_APPLY_FEES to pass the value in the PIN_FLD_CHARGES array or the PIN_FLD_FAILED_PAYMENT_FEE field in the PIN_FLD_EXTENDED_INFO substruct.

  3. Use PDC or Pricing Center to create the charges for the new attribute values.

Processing Payment Incentives

Payment incentives are implemented by calling PCM_OP_PYMT_PROVISION_INCENTIVE and PCM_OP_PYMT_GRANT_INCENTIVE.

PCM_OP_PYMT_PROVISION_INCENTIVE evaluates a payment to determine whether a payment incentive should be provisioned and, if so, sets the payment incentive trigger. If a payment incentive is triggered, PCM_OP_PYMT_GRANT_INCENTIVE performs the incentive.

PCM_OP_PYMT_PROVISION_INCENTIVE is called by PCM_OP_BILL_ITEM_TRANSFER immediately after payment allocation, provided BRM is configured for payment incentives. PCM_OP_PYMT_PROVISION_INCENTIVE determines whether the payment resulted in an early, in-full settlement of the last bill. If so, the current bill may be eligible for a payment incentive. This opcode creates a trigger for payment incentive processing to apply an incentive.

For more information, see "Triggering Payment Incentives" and "Granting Payment Incentives".

Triggering Payment Incentives

PCM_OP_PYMT_POL_PROVISION_INCENTIVE is called by PCM_OP_BILL_ITEM_TRANSFER immediately after payment allocation, provided BRM is configured for payment incentives.

You can customize PCM_OP_PYMT_POL_PROVISION_INCENTIVE to provide the timestamp from a field other than PIN_FLD_END_T (for example, PIN_FLD_EFFECTIVE_T) or to apply business logic that determines the payment date. For example, you can customize PCM_OP_PYMT_POL_PROVISION_INCENTIVE to use the payment receipt date as the payment timestamp for all credit card payments and three days after the payment receipt date for all check payments.

PCM_OP_PYMT_PROVISION_INCENTIVE determines whether the payment resulted in an early, in-full settlement of the last bill. If so, the current bill may be eligible for a payment incentive and PCM_OP_PYMT_POL_PROVISION_INCENTIVE creates a trigger for payment incentive processing to apply an incentive.

PCM_OP_PYMT_POL_PROVISION_INCENTIVE is called by PCM_OP_PYMT_PROVISION_INCENTIVE to provide the payment date that is used when determining whether the bill was paid on time. It receives the POID of the /event/billing/payment object in the input flist and reads this object to determine the payment date. By default, PCM_OP_PYMT_POL_PROVISION_INCENTIVE reads the PIN_FLD_END_T field to obtain the timestamp. If it finds a payment date it's configured to provide, it returns the date to PCM_OP_PYMT_PROVISION_INCENTIVE, which performs the following tasks:

  • Retrieves the bill for which the payment allocation was made.

  • Determines if the bill was the last bill.

  • Compares the timestamp provided by the opcode to the due date for the payment.

PCM_OP_PYMT_PROVISION_INCENTIVE performs the following functions:

  1. It calls PCM_OP_PYMT_POL_PROVISION_INCENTIVE to determine if the PIN_EFFECTIVE_T field or any other customizable field contains a payment timestamp. See "Triggering Payment Incentives".

  2. It retrieves all of the bills and determines whether each of the bills is from the last billing cycle or a prior cycle. PCM_OP_PYMT_PROVISION_INCENTIVE is only concerned with the bills from the last billing cycles; none of the other bills qualify for early incentives.

  3. It reads the Due and Due Time in each /bill object. PCM_OP_PYMT_PROVISION_INCENTIVE uses this information along with the timestamp in the PIN_FLD_END_T field from the /event/billing/payment object or a timestamp from the policy opcode to determine whether the payment for a given bill was allocated in full and early. PCM_OP_PYMT_PROVISION_INCENTIVE must find the following conditions:

    • PIN_FLD_DUE must be 0, indicating that there are no more payments due for the bill, and it was paid in full.

    • The timestamp in PIN_FLD_END_T or the timestamp provided by the policy opcode must be earlier than or the same as the one in PIN_FLD_DUE_T, indicating that the payment was allocated before or at the same time as the due time. BRM considers both of these conditions to be indications of an early payment.

    BRM always attempts to use whatever timestamp the policy opcode provides. PCM_OP_PYMT_PROVISION_INCENTIVE only uses PIN_FLD_END_T if the policy opcode does not return a timestamp or returns PIN_FLD_END_T instead of some other timestamp.

  4. If the payment meets these conditions, PCM_OP_PYMT_PROVISION_INCENTIVE modifies the /billinfo object by setting its PIN_FLD_PAYMENT_EVENT_OBJ field to the POID of the payment event that resulted in early, in-full payment. This acts as a trigger for granting the payment incentive during the billing run.

  5. It returns a list of bill units to which it added the payment incentive.

Granting Payment Incentives

PCM_OP_PYMT_GRANT_INCENTIVE is called by PCM_OP_BILL_MAKE_BILL as part of the billing run. PCM_OP_PYMT_GRANT_INCENTIVE grants payment incentives based on:

  • Whether the account has purchased a payment incentive subscription charge offer or the account is eligible for a system charge offer that includes a payment incentive.

  • Whether the payment incentive trigger is set in the bill unit.

  • Conditions specified in the charge.

  • Any additional conditions specified in PCM_OP_PYMT_POL_GRANT_INCENTIVE.

PCM_OP_PYMT_GRANT_INCENTIVE performs the following functions:

  1. If the bill qualifies for a payment incentive, the opcode uses information from the /account and /event/billing/payment objects to enrich the input flist with the payment method, payment channel, and customer segment list. It also includes:

    • The total for the current bill calculated during the current billing run.

    • The total for the last bill, as determined from the /bill object for that bill.

    By default, both these totals are after-tax amounts.

  2. It calls PCM_OP_PYMT_POL_GRANT_INCENTIVE to determine whether it must enrich the input flist with any extra fields, and validates the fields returned by the policy opcode.

  3. It creates an /item/incentive object and an /event/billing/incentive object for the bill. In addition to the payment method, payment channel, and so on, the /event/billing/incentive object contains any fields specified in PCM_OP_PYMT_POL_GRANT_INCENTIVE, provided the object has been suitably extended.

  4. It sends the event to the rating opcodes to calculate the payment incentive for each bill. BRM applies the balance impact of the payment incentive event to the default balance group of the bill unit.

  5. It clears the payment incentive trigger in the PIN_FLD_PAYMENT_EVENT_OBJ field of the /billinfo objects of each affected bill, returning this field to a null value.

Two other opcodes are used for payment incentives:

Reversing Payment Incentives

PCM_OP_PYMT_REVERSE_INCENTIVE reverses a payment incentive if it has not yet been granted.

PCM_OP_PYMT_REVERSE_INCENTIVE is called by PCM_OP_BILL_REVERSE_PAYMENT as part of payment reversal, provided BRM is configured for payment incentives. It determines whether payment is being reversed for a bill that had a payment incentive either provisioned or granted. If so, it either deactivates the payment incentive trigger or, for payment incentives that have already been granted, issues warnings and flags the reversal event so that you can initiate manual processing.

PCM_OP_PYMT_REVERSE_INCENTIVE performs the following functions:

  1. It retrieves all bills affected by the reversal and searches for the associated /billinfo objects.

  2. For each /billinfo object, it checks the PIN_FLD_PAYMENT_EVENT_OBJ field to determine whether a payment incentive has been provisioned but not yet granted. If so, it resets this field, removing the POID of the payment event, which automatically reverses the payment incentive.

  3. If the PIN_FLD_PAYMENT_EVENT_OBJ field does not indicate that a payment incentive has been provisioned, the opcode searches all /event/billing/incentive objects for the account to determine whether any of them are associated with the bill for which payment is being reversed.

    The existence of this object for a given bill means that BRM already granted a payment incentive for the bill. In this case, the opcode generates a warning in the cm.pinlog file to indicate that manual adjustment is required.

Customizing Payment Incentives

You can configure BRM to grant payment incentives. See BRM Configuring and Collecting Payments.

To customize payment incentives, read the following:

Customizing How to Trigger Payment Incentives

You can configure the PCM_OP_PYMT_POL_PROVISION_INCENTIVE policy opcode to determine the payment date that should be considered when provisioning incentives.

For example, you can customize this opcode to use the payment receipt date as the payment timestamp for all credit card payments, and 3 days after the payment receipt date for all check payments.

You can also create custom payment objects that use fields other than a payment due date. In this case, you would customize this policy opcode to read these fields and provide them as output for PCM_OP_PYMT_PROVISION_INCENTIVE.

See the chapter about payments in BRM Opcode Guide for more information.

Customizing How to Grant Payment Incentives

By default, you can set up a charge so that BRM considers three attributes when determining whether to apply a payment incentive:

  • Customer segment

  • Payment channel

  • Payment method

You can broaden this scope by customizing the PCM_OP_PYMT_POL_GRANT_INCENTIVE policy opcode. When you customize this opcode, you must also extend the /event/billing/incentive storable class so that the object records all the criteria considered for the payment incentive. The additional fields are then included in the choices you can make when creating charge selectors in PDC or Pricing Center. Therefore, you can use these additional fields as criteria when defining attribute combinations that result in payment incentives.

The contents of the /event/billing/incentive object determine:

  • The list of attributes that can be considered when setting up a charge. The pricing expert associates combinations of these attributes with specific charges when creating the payment incentive charge offer.

  • The information BRM compares with the attribute combinations defined for the payment incentive charge offer. If BRM finds a match, it rates the payment incentive event according to the charge for the matching combination.

For example, to award a payment incentive to premium customers who pay in a certain currency, you perform two tasks:

  • Customize PCM_OP_PYMT_POL_GRANT_INCENTIVE by adding the PIN_FLD_SERVICE_OBJ and PIN_FLD_CURRENCY fields to the input flist. The opcode then includes the service type for the account and the currency type in the output flist. As a result, BRM is able to consider the service type and currency along with the usual criteria when determining whether to apply the incentive and when calculating the payment incentive.

  • Extend the /event/billing/incentive storable class by adding the PIN_FLD_SERVICE_OBJ and PIN_FLD_CURRENCY fields. BRM then includes the service type and currency in the event object each time it's created. When you create columns in the charge selector, you can select these two fields along with the default fields.

In addition to performing this type of customization, you can also customize the PCM_OP_PYMT_POL_GRANT_INCENTIVE policy opcode to do the following:

  • Provide special types of incentives such as free gifts. In this case, you modify the opcode so that it calls the opcodes that process and control charge offer purchases, for example, PCM_OP_SUBSCRIPTION_PURCHASE_DEAL. Then, you create a bundle that includes an item charge offer that awards the free gift.

  • Develop an application to count the number of subscription services for an account and customize PCM_OP_PYMT_POL_GRANT_INCENTIVE to include this information in the enriched flist.

  • Customize which customer segment to use. You can also customize this opcode to select a different customer segment from PIN_FLD_CUSTOMER_SEGMENT_LIST. By default, PCM_OP_PYMT_POL_GRANT_INCENTIVE selects the first customer segment from the PIN_FLD_CUSTOMER_SEGMENT_LIST it gets from PCM_OP_PYMT_GRANT_INCENTIVE. The customer segment returned by PCM_OP_PYMT_POL_GRANT_INCENTIVE is the one that BRM uses as a filtering attribute during payment incentive calculation.

    See the chapter about payments in BRM Opcode Guide for more information

Manually Reversing a Payment Incentive

When a payment is reversed, BRM reverses any payment incentive provisioning triggers created at payment time, provided the payment was for the last bill. If payment was reversed for an earlier bill, BRM has already applied the incentive and does not reverse it. In this case, you must perform a manual account adjustment through your CRM client application. This type of adjustment debits account balances rather than crediting them.

BRM identifies payment incentives that need manual reversal in the cm.pinlog file, which lists any cases where a payment incentive reversal failed. Searching the cm.pinlog for this information can be time consuming. Therefore, you should consider customizing this process in one of the following ways:

  • Write your own reporting application that creates a list of all bills that meet the following two conditions:

    • The bill had a payment incentive that was not only provisioned, but also granted.

    • The payment reversal was for the bill before the one that had the payment incentive granted.

    Operations personnel can use this report to identify the adjustments they must perform.

  • Create your own custom opcode or customize the PCM_OP_ACT_POL_EVENT_NOTIFY policy opcode so that it checks the reporting conditions discussed above and alerts the CRM client application whenever both conditions are true. Then, enable event notification and add the following information to your system's event notification list so that BRM calls PCM_OP_ACT_POL_EVENT_NOTIFY (opcode number 301) each time an /event/billing/reversal/* event is generated during payment reversal:

    # comment, if any
    301    0    /event/billing/reversal/cc
    301    0    /event/billing/reversal/check
    301    0    /event/billing/reversal/dd
    301    0    /event/billing/reversal/payorder 
    301    0    /event/billing/reversal/postalorder
    301    0    /event/billing/reversal/transfer
    

    For more information, see "Using Event Notification" in BRM Developer's Guide.

    In addition, you must customize your middleware and CRM applications to process the notification correctly and issue appropriate messages to operations personnel.

Managing Top-Ups

See the following for information about managing top-ups in your client applications:

Setting Up Top-Up Information in an Account

To create or modify an account's top-up information, PCM_OP_CUST_SET_TOPUP calls one of the following opcodes:

  • PCM_OP_CUST_CREATE_TOPUP

  • PCM_OP_CUST_MODIFY_TOPUP

If successful, the PCM_OP_CUST_SET_TOPUP output flist contains the PIN_FLD_POID set to the POID of the created or modified /topup object.

If unsuccessful, the PCM_OP_CUST_SET_TOPUP output flist contains the following:

  • PIN_FLD_FIELD_NUM set to the field that failed.

  • PIN_FLD_TYPE set to the type of field that failed.

  • PIN_FLD_RESULT set to the validation error code.

For standard top-ups, an account's top-up information is stored in one object (/topup), but for sponsored top-ups, an account's top-up information is stored in two objects (/topup and /group/topup). Sometimes, one of the objects must be created and the other modified. For example, to add a member account to a sponsored top-up group, BRM might need to create a /topup object for the member and associate it with an existing /group/topup object. To determine which opcode to call in such cases, PCM_OP_CUST_SET_TOPUP uses these rules:

  • If at least one of the objects is being created, PCM_OP_CUST_SET_TOPUP calls PCM_OP_CUST_CREATE_TOPUP. This is true even if the other object is being modified.

  • If neither object is being created, PCM_OP_CUST_SET_TOPUP calls PCM_OP_CUST_MODIFY_TOPUP.

Preparing an Account's Top-Up Information

To prepare top-up information for an account, PCM_OP_CUST_CREATE_TOPUP and PCM_OP_CUST_MODIFY_TOPUP call PCM_OP_CUST_POL_PREP_TOPUP. For example, you can customize PCM_OP_CUST_POL_PREP_TOPUP to enable member accounts to change their top-up PINs and membership status. The policy opcode prepares information required to perform one of these tasks:

  • Create a standalone /topup object for standard top-ups. This occurs when the following information is not passed to PCM_OP_CUST_POL_PREP_TOPUP:

    • A /topup object POID

    • A sponsored top-up group owner account POID

  • Modify a standalone /topup object for standard top-ups. This occurs when the following information is passed to PCM_OP_CUST_POL_PREP_TOPUP:

    • A /topup object POID

    But this information is not passed to it:

    • A sponsored top-up group owner account POID

    • A /group/topup POID

  • Create one or both objects (/topup and /group/topup) for sponsored top-ups. This occurs when the following information is passed to PCM_OP_CUST_POL_PREP_TOPUP:

    • A sponsored top-up group owner account POID

    But this information is not passed to it:

    • A /topup object POID

    • A /group/topup POID

      Note:

      Before creating a /group/topup object, the opcode checks for an existing /group/topup object that matches the criteria in its input flist. For more information, see "Finding Sponsored Top-Up Groups".

  • Modify both objects (/topup and /group/topup) for sponsored top-ups. This occurs when the following information is passed to PCM_OP_CUST_POL_PREP_TOPUP:

    • A /topup object POID

    • A /group/topup POID

Additional Preparation for Sponsored Top-Ups

For sponsored top-ups, PCM_OP_CUST_POL_PREP_TOPUP also prepares this information:

  • If the group owner account did not initiate the object creation or modification, the policy opcode sets the following values in its output flist:

    • PIN_FLD_STATUS (member account's group membership status) = the value associated with the PIN_STATUS_INACTIVE status in the BRM_home/include/ops/pcm.h header file

    • PIN_FLD_PIN (member account's top-up PIN) = NULL

  • If the group owner account did initiate the object creation or modification, the policy opcode does the following:

    • If the status of the member account's group membership is not specified in the input flist, sets it to the value associated with the PIN_STATUS_ACTIVE in the BRM_home/include/ops/pcm.h header file

    • (Creation only) If the group name is not specified in the input flist, sets the name to default

Additional Preparation for Recurring Top-Ups

For recurring top-ups, PCM_OP_CUST_POL_PREP_TOPUP also prepares this information:

Validating an Account's Top-Up Information

To validate the top-up information prepared for an account (see "Preparing an Account's Top-Up Information"), PCM_OP_CUST_CREATE_TOPUP and PCM_OP_CUST_MODIFY_TOPUP call PCM_OP_CUST_POL_VALID_TOPUP. The policy opcode performs these tasks:

  • Verifies that the status of the account to be debited for each top-up (the paying account) is active.

  • Verifies that the standard or sponsored top-up amount is less than or equal to the corresponding top-up cap.

  • (Sponsored top-ups only) Verifies that the member is not trying to join a group that it owns.

  • (Sponsored top-ups only) Verifies that the prospective member's account is not closed.

  • (Sponsored top-ups only) Verifies that the prospective member is not a member of any other sponsored top-up group.

You can customize PCM_OP_CUST_POL_VALID_TOPUP to change the way it validates the PCM_OP_CUST_POL_PREP_TOPUP output flist.

In its own output flist, PCM_OP_CUST_POL_VALID_TOPUP returns a PIN_FLD_RESULT value that is associated with one of the following values:

  • PIN_RESULT_PASS (validation succeeded)

  • PIN_RESULT_FAIL (validation failed)

PCM_OP_CUST_POL_VALID_TOPUPis not called by any opcode.

Finding Top-Up Events

PCM_OP_PYMT_FIND_TOPUP_EVENTS finds the /event/billing/adjustment/account event associated with sponsored top-ups.

By default, this opcode returns data from all the fields in an event. To return data from only particular event fields, specify the fields in the PIN_FLD_RESULTS array in this opcode's input flist.

Creating an Account's Top-Up Information

If validation succeeds (see "Validating an Account's Top-Up Information"), the validated information is used to create top-up information.

PCM_OP_CUST_CREATE_TOPUP uses the validated information to perform one of these operations:

  • If the information does not include the POID of a sponsored top-up group owner account, the opcode:

    • Creates a standalone /topup object that contains information about the type of top-up to perform.

    • For recurring top-ups, calls PCM_OP_PYMT_TOPUP to perform the first top-up. See "How BRM Handles Recurring Standard Top-Ups".

    • Generates an /event/notification/topup/create event.

  • If the information includes the POID of a sponsored top-up group owner account and /group/topup and /topup POID types, the opcode creates a sponsored top-up relationship as follows:

    1. Creates a /group/topup object for the owner account

    2. Creates a /topup object for the member account

    3. Associates the new /topup object with the new /group/topup object

  • If the information includes the POID of a sponsored top-up group owner account, the POID of an existing /group/topup object, and a /topup POID type, PCM_OP_CUST_CREATE_TOPUP creates a sponsored top-up relationship as follows:

    1. Creates a /topup object for the member account

    2. Associates the new /topup object with the existing /group/topup object

  • If the information includes the POID of a sponsored top-up group owner account, a /group/topup POID type, and an existing /topup object, PCM_OP_CUST_CREATE_TOPUP creates a sponsored top-up as follows:

    1. Creates a /group/topup object for the owner account

    2. Associates the existing /topup object with the new /group/topup object

If successful, the PCM_OP_CUST_CREATE_TOPUP output flist contains the following:

  • PIN_FLD_POID set to the POID of the /topup object created

If unsuccessful, the output flist contains the following:

  • PIN_FLD_FIELD_NUM set to the field that failed

  • PIN_FLD_TYPE set to the type of field that failed

  • PIN_FLD_RESULT set to the validation error code

Modifying an Account's Top-Up Information

If validation succeeds (see "Validating an Account's Top-Up Information"), the validated information is used to modify top-up information.

PCM_OP_CUST_MODIFY_TOPUP uses the validated information to perform one of these operations:

  • If the information does not include the POID of an existing /group/topup object, the opcode:

    • Modifies the standalone /topup object.

    • For recurring top-ups, calls PCM_OP_PYMT_TOPUP to perform the first top-up. See "How BRM Handles Recurring Standard Top-Ups".

    • Generates an /event/notification/topup/modify event.

  • If the information includes the POID of an existing /group/topup object, the opcode modifies the sponsored top-up information in the /group/topup and /topup objects.

If successful, the PCM_OP_CUST_MODIFY_TOPUP output flist contains the following:

  • PIN_FLD_POID set to the POID of the /topup object modified

If unsuccessful, the PCM_OP_CUST_MODIFY_TOPUP output flist contains the following:

  • PIN_FLD_FIELD_NUM set to the field that failed

  • PIN_FLD_TYPE set to the type of field that failed

  • PIN_FLD_RESULT set to the validation error code

Deleting Top-Ups

Use PCM_OP_CUST_DELETE_TOPUP to delete /topup objects.

PCM_OP_CUST_DELETE_TOPUP is called by PCM_OP_CUST_DELETE_ACCT.

This opcode should not be used to cancel an account's membership in a sponsored top-up group.

Finding Sponsored Top-Up Groups

When setting up sponsored top-ups, PCM_OP_CUST_POL_PREP_TOPUP uses the following information from the PCM_OP_CUST_SET_TOPUP input flist to determine whether the prospective member account can be added to an existing group:

  • The group owner account POID (PIN_FLD_PARENT)

  • The name of the group (PIN_FLD_NAME)

    Note:

    Each group owned by the same account must have a unique name. Groups owned by different accounts can have the same name.

If a group name is not provided, the policy opcode searches for a group by owner account POID and the ID of the balance or balances that you want to top-up in the member account (PIN_FLD_RESOURCE_ID in the LIMITS array). The search has the following results:

  • If the policy opcode finds the group by name but a balance is specified in the input flist that the group does not support, the following occurs:

    • If the group owner account initiated the transaction, the balance is added to the group.

    • If the member account initiated the transaction, an error is returned.

  • If the policy opcode finds the group by balance and the search returns multiple groups, the groups are listed alphabetically by PIN_FLD_NAME value and the member is added to the group at the top of the list.

  • If the policy opcode fails to find a group by name or by balance, the following occurs:

    • If the group owner account has a group named default, the member is added to that group.

    • If the group owner account does not have a group named default, such a group is created based on the information in the input flist. (Each group owner can have only one sponsored top-up group named default.)

      Note:

      To change the way the search is performed, customize PCM_OP_CUST_POL_PREP_TOPUP.

Setting a Customer's Automatic Top-Up Threshold

You can set a fixed or percentage-based threshold below which an automatic top-up will be triggered for a customer. The thresholds are stored in /config/credit_profile objects, which are tied to a customer's balance group.

To set an automatic top-up threshold, use PCM_OP_BILL_SET_LIMIT_AND_CR. Specify the PIN_FLD_RESRC_FIXED_THRESHOLD or PIN_FLD_RESRC_PERC_THRESHOLD fields in the PIN_FLD_LIMIT array of the input flist, using the appropriate resource ID for the limit array.

For example, to set a threshold of $5 in USD (resource ID 840):

0 PIN_FLD_PROGRAM_NAME 		STR [0] "calling_program"
0 PIN_FLD_POID 			POID [0] 0.0.0.1 /account 371077 10
0 PIN_FLD_LIMIT         	ARRAY [840] allocated 1, used 1
1       PIN_FLD_RESRC_FIXED_THRESHOLD DECIMAL [0] 5.0

Processing Top-Ups

BRM uses the PCM_OP_PYMT_TOPUP opcode to process all top-up payments. See the following topics:

Triggering Top-ups

PCM_OP_PYMT_TOPUP is triggered as follows:

  • Manual top-ups: When a customer or CSR uses a client application to top up a balance in an account (a manual top-up), the opcode is called by the client application.

  • Automatic standard top-ups: When a balance in an account configured for automatic standard top-ups falls below a specified threshold, ECE calls PCM_OP_PYMT_TOPUP.

  • Recurring standard top-ups: When you run the pin_balance_transfer utility with the -standard parameter. The utility calls the opcode to top up all accounts with a recurring top-up and a top-up due date of today.

  • Automatic sponsored top-ups: When you run the pin_balance_transfer utility with the -start mm/dd/yy and -end mm/dd/yy parameters. The utility calls the opcode to top up all accounts configured for automatic sponsored top-ups and a next automatic top-up date in the time range specified in the pin_balance_transfer utility's command-line parameters.

How BRM Handles Manual Standard Top-Ups

For manual standard top-ups, PCM_OP_PYMT_TOPUP does the following:

  1. Depending on the payment method, does one of the following:
    • For voucher payment methods, calls PCM_OP_PYMT_POL_VALID_VOUCHER to perform these operations:
      • Call your voucher management system to validate the voucher and retrieve the balance impacts of the voucher's balances.
      • Determine whether the voucher has a currency balance, a noncurrency balance, or both.
      • Use the balance with the earliest validity start date and the balance with the latest validity end date to determine the validity period of the voucher.
      • Call PCM_OP_VOUCHER_ASSOCIATE_VOUCHER to associate the voucher with the account.
      • Return the preceding information and the voucher's balance impacts to PCM_OP_PYMT_TOPUP.
    • For credit card and direct debit payment methods, collects payment from the credit card agency or direct debit company, and then updates the specified balance.
    • For cash and check payment methods, receives the payment amount from the client application.
  2. Calls PCM_OP_ACT_USAGE to generate an /event/billing/topup event.
  3. If there are any /item/loan_fee and /item/loan_debit items for the account:
    1. Transfers the corresponding amount from the top-up to pay off the loan. If the amount in the top-up is less than the amount due for the loan, one of the following happens:
      • The percent configured in the loan_repayment_percent business parameter is transferred and any remaining percent is credited to the main account balance.
      • If the PCM_OP_LOAN_POL_PRE_RECOVER_LOAN has been customized for this scenario, the top-up is rejected and the customer is notified.
    2. Calls PCM_OP_BILL_SET_LIMIT_AND_CR to subtract the amount from the balance group's PIN_FLD_OUTSTANDING_AMOUNT field.
    3. Calls PCM_OP_CUST_MODIFY_PROFILE to subtract the amount from the loan profile's PIN_FLD_OUTSTANDING_AMOUNT field.
  4. If topping up a noncurrency balance, does the following:
    • Calls PCM_OP_PYMT_POL_TOPUP_SET_VALIDITY to perform any customization on the validity dates for the noncurrency balance. By default, it does nothing.
    • Calls PCM_OP_BILL_DEBIT to apply a credit to the account's noncurrency sub-balance.

    Note:

    The cash and check payment methods do not support noncurrency balance top-ups.

  5. If topping up a currency balance, calls PCM_OP_PYMT_COLLECT to apply a credit to the account's currency sub-balance.
  6. Applies any top-up discount incentives to the account by calling PCM_OP_PYMT_POL_PURCHASE_DEAL.
How BRM Handles Automatic Standard Top-Ups

PCM_OP_PYMT_TOPUP performs automatic standard top-ups as follows:

  1. Collects payment from the credit card agency or direct debit company, and then updates the specified balance.

    Note:

    Automatic standard top-ups support only the credit card and debit card payment methods.

  2. Calls PCM_OP_ACT_USAGE to generate an /event/billing/topup event.
  3. Retrieves the top-up amount from the specified /topup object.
  4. Verifies that the top-up amount will not cause the sum of all automatic standard top-ups received during the current accounting cycle to exceed the account's automatic standard top-up cap.
  5. If there are any /item/loan_fee and /item/loan_debit items for the account:
    1. Transfers the corresponding amount from the top-up to pay off the loan. If the amount in the top-up is less than the amount due for the loan, one of the following happens:
      • The percent configured in the loan_repayment_percent business parameter is transferred and any remaining percent is credited to the main account balance.
      • If the PCM_OP_LOAN_POL_PRE_RECOVER_LOAN has been customized for this scenario, the top-up is rejected and the customer is notified.
    2. Calls PCM_OP_BILL_SET_LIMIT_AND_CR to subtract the amount from the balance group's PIN_FLD_OUTSTANDING_AMOUNT field.
    3. Calls PCM_OP_CUST_MODIFY_PROFILE to subtract the amount from the loan profile's PIN_FLD_OUTSTANDING_AMOUNT field.
  6. If topping up a noncurrency balance, does the following:
    • Calls PCM_OP_PYMT_POL_TOPUP_SET_VALIDITY to perform any customization on the validity dates for the noncurrency balance. By default, it does nothing.
    • Calls PCM_OP_BILL_DEBIT to apply a credit to the account's noncurrency sub-balance.
  7. If topping up a currency balance, calls PCM_OP_PYMT_COLLECT to apply a credit to the account's currency sub-balance.
  8. Applies any top-up discount incentives to the account by calling PCM_OP_PYMT_POL_PURCHASE_DEAL.
How BRM Handles Recurring Standard Top-Ups

PCM_OP_PYMT_TOPUP performs recurring standard top-ups as follows:

  1. Depending on the payment method, does one of the following:
    • For voucher payment methods, calls PCM_OP_PYMT_POL_VALID_VOUCHER to perform these operations:
      • Call your voucher management system to validate the voucher and retrieve the balance impacts of the voucher's balances.
      • Determine whether the voucher has a currency balance, a noncurrency balance, or both.
      • Use the balance with the earliest validity start date and the balance with the latest validity end date to determine the validity period of the voucher.
      • Call PCM_OP_VOUCHER_ASSOCIATE_VOUCHER to associate the voucher with the account.
      • Return the preceding information and the voucher's balance impacts to PCM_OP_PYMT_TOPUP.
    • For credit card and direct debit payment methods, collects payment from the credit card agency or direct debit company, and then updates the specified balance.
  2. Calls PCM_OP_ACT_USAGE to generate an /event/billing/topup event.
  3. Retrieves the top-up amount and resource ID from the specified /topup object.
  4. Verifies that the number of recurring top-ups performed (in the /topup object's PIN_FLD_NUM_TOPUPS_DONE field) is less than the maximum number of recurring top-ups allowed (in the /topup object's PIN_FLD_NUM_TOPUPS field).

    After PIN_FLD_NUM_TOPUPS_DONE equals the value set in PIN_FLD_NUM_TOPUPS, no further recurring top-ups are performed.

  5. If there are any /item/loan_fee and /item/loan_debit items for the account:
    1. Transfers the corresponding amount from the top-up to pay off the loan. If the amount in the top-up is less than the amount due for the loan, one of the following happens:
      • The percent configured in the loan_repayment_percent business parameter is transferred and any remaining percent is credited to the main account balance.
      • If the PCM_OP_LOAN_POL_PRE_RECOVER_LOAN has been customized for this scenario, the top-up is rejected and the customer is notified.
    2. Calls PCM_OP_BILL_SET_LIMIT_AND_CR to subtract the amount from the balance group's PIN_FLD_OUTSTANDING_AMOUNT field.
    3. Calls PCM_OP_CUST_MODIFY_PROFILE to subtract the amount from the loan profile's PIN_FLD_OUTSTANDING_AMOUNT field.
  6. If topping up a noncurrency balance, does the following:
    • Calls PCM_OP_PYMT_POL_TOPUP_SET_VALIDITY to perform any customization on the validity dates for the noncurrency balance. By default, it does nothing.
    • Calls PCM_OP_BILL_DEBIT to apply a credit to the account's noncurrency sub-balance.
  7. If topping up a currency balance, calls PCM_OP_PYMT_COLLECT to apply a credit to the account's currency sub-balance.
  8. Applies any top-up discount incentives to the account by calling PCM_OP_PYMT_POL_PURCHASE_DEAL.
  9. Calls PCM_OP_SUBSCRIPTION_CALCULATE_VALIDITY to calculate the due date for the next recurring top-up, which is set in the /topup object's PIN_FLD_NEXT_TOPUP_T field. It also increments the number of recurring top-ups completed by one in the /topup object's PIN_FLD_NUM_TOPUPS_DONE field.
  10. Calls PCM_OP_PYMT_POL_POST_TOPUP to perform any customizations to the due date for the next recurring top-up. By default, this policy opcode does nothing.
How BRM Handles Manual Sponsored Top-Ups

PCM_OP_PYMT_TOPUP performs manual sponsored top-ups as follows:

  1. Receives the top-up amount from a client application.
  2. Verifies the following:
    • The status of the member is active.
    • (Member-initiated top-ups only) The top-up PIN is valid.
    • The top-up amount will not cause the total amount of credit charged to the owner account's balance group to exceed the credit limit of the associated balance in that balance group.
    • The top-up amount will not cause the sum of all top-ups received during the current accounting cycle of the owner account to exceed the group's top-up cap.
  3. Performs these operations:
    • Calls PCM_OP_BILL_TRANSFER_BALANCE to transfer the top-up balances from the paying balance group to the receiving balance group.
    • Passes the reason ID and the reason domain ID used to differentiate sponsored top-up adjustments from other types of adjustments to PCM_OP_BILL_TRANSFER_BALANCE, which passes them to PCM_OP_AR_ACCOUNT_ADJUSTMENT.
    • Updates the sum of all sponsored top-ups credited to members of the group during the group owner account's current accounting cycle. This value is stored in the PIN_FLD_CYCLE_TOPPED_AMT field of the LIMITS array in the /group/topup object.

      If the last sponsored top-up occurred in the owner account's current accounting cycle, PCM_OP_PYMT_TOPUP adds the amount of the current top-up to the value already in this field.

      If the last sponsored top-up occurred in the owner account's previous accounting cycle, the opcode sets this field to the amount of the current top-up.

  4. If there are any /item/loan_fee and /item/loan_debit items for the account:
    1. Transfers the corresponding amount from the top-up to pay off the loan. If the amount in the top-up is less than the amount due for the loan, one of the following happens:
      • The percent configured in the loan_repayment_percent business parameter is transferred and any remaining percent is credited to the main account balance.
      • If the PCM_OP_LOAN_POL_PRE_RECOVER_LOAN has been customized for this scenario, the top-up is rejected and the customer is notified.
    2. Calls PCM_OP_BILL_SET_LIMIT_AND_CR to subtract the amount from the balance group's PIN_FLD_OUTSTANDING_AMOUNT field.
    3. Calls PCM_OP_CUST_MODIFY_PROFILE to subtract the amount from the loan profile's PIN_FLD_OUTSTANDING_AMOUNT field.
  5. Applies any top-up discount incentives to the account by calling PCM_OP_PYMT_POL_PURCHASE_DEAL.
How BRM Handles Automatic Sponsored Top-Ups

PCM_OP_PYMT_TOPUP performs automatic sponsored top-ups as follows:

  1. Retrieves the top-up amount from the specified /group/topup object.
  2. Verifies the following:
    • The status of the member is active.
    • The top-up amount will not cause the total amount of credit charged to the owner account's balance group to exceed the credit limit of the associated balance in that balance group.
    • The top-up amount will not cause the sum of all top-ups received during the current accounting cycle of the owner account to exceed the group's top-up cap.
  3. Performs these operations:
    • Calls PCM_OP_BILL_TRANSFER_BALANCE to transfer the top-up balances from the paying balance group to the receiving balance group.
    • Passes the reason ID and the reason domain ID used to differentiate sponsored top-up adjustments from other types of adjustments to PCM_OP_BILL_TRANSFER_BALANCE, which passes them to PCM_OP_AR_ACCOUNT_ADJUSTMENT.
    • Updates the time that the member's last automatic sponsored top-up occurred to the current time.

      This value is stored in the PIN_FLD_LAST_TOPUP_T field of the LIMITS array in the /group/topup object. PCM_OP_PYMT_TOPUP uses this value to determine when to run the member's next automatic sponsored top-up.

    • Calculates the time that the member's next automatic sponsored top-up will occur. This value is stored in the PIN_FLD_NEXT_TOPUP_T field of the LIMITS array in the /group/topup object.
    • Updates the sum of all sponsored top-ups credited to members of the group during the group owner account's current accounting cycle. This value is stored in the PIN_FLD_CYCLE_TOPPED_AMT field of the LIMITS array in the /group/topup object.

      If the last sponsored top-up occurred in the owner account's current accounting cycle, PCM_OP_PYMT_TOPUP adds the amount of the current top-up to the value already in this field.

      If the last sponsored top-up occurred in the owner account's previous accounting cycle, the opcode sets this field to the amount of the current top-up.

  4. If there are any /item/loan_fee and /item/loan_debit items for the account:
    1. Transfers the corresponding amount from the top-up to pay off the loan. If the amount in the top-up is less than the amount due for the loan, one of the following happens:
      • The percent configured in the loan_repayment_percent business parameter is transferred and any remaining percent is credited to the main account balance.
      • If the PCM_OP_LOAN_POL_PRE_RECOVER_LOAN has been customized for this scenario, the top-up is rejected and the customer is notified.
    2. Calls PCM_OP_BILL_SET_LIMIT_AND_CR to subtract the amount from the balance group's PIN_FLD_OUTSTANDING_AMOUNT field.
    3. Calls PCM_OP_CUST_MODIFY_PROFILE to subtract the amount from the loan profile's PIN_FLD_OUTSTANDING_AMOUNT field.
  5. Applies any top-up discount incentives to the account by calling PCM_OP_PYMT_POL_PURCHASE_DEAL.

Implementing Top-Ups in Custom Client Applications

All top-ups are performed by PCM_OP_PYMT_TOPUP. See the following topics:

Implementing Manual Standard Top-Ups

To implement the manual standard top-up feature, configure your custom client application to accept the following top-up information and pass it in the input flist to the PCM_OP_PYMT_TOPUP opcode:

  • For voucher top-ups, pass the following information in the PIN_FLD_VOUCHERS_INFO array:

    • Voucher serial number

    • Voucher PIN number

    • Bill unit (/billinfo object) to top up

    • Balance group to top up (optional)

    • Amount to top up (also include the resource ID for noncurrency resources)

    • Service to top up

      Note:

      To apply the voucher top up to a service-level balance group, you must pass the /service object POID in the PIN_FLD_SERVICE_OBJ field of the PIN_FLD_VOUCHERS_INFO array.

  • For credit card top ups, pass the following information in the PIN_FLD_TOPUP_INFO array:

    • Bill unit to top up

    • Balance group to top up (optional)

    • Amount to top up (also include the resource ID for noncurrency resources)

    • Credit card number

    • Credit card expiration date

    • Credit card owner's name and address information

  • For direct debit top ups, pass the following information in the PIN_FLD_TOPUP_INFO array:

    • Bill unit to top up

    • Balance group to top up (optional)

    • Amount to top up (also include the resource ID for noncurrency resources)

    • Bank routing number

    • Bank account number

    • Direct debit owner's name and address information

Implementing Automatic Standard Top-Ups

To implement the automatic standard top-up feature:

  1. In PDC or Pricing Center, set a credit floor and credit threshold for any package that contains bundles whose service balances you want your customers to top up. For example, to trigger an automatic standard top-up when an account balance falls below $30, set the credit floor to -100 and the threshold to 70%.

  2. Configure your custom client application to accept the following top-up information:

    • Payment method

      To specify the payment method for automatic standard top-ups, set the appropriate value in the PIN_FLD_PAYINFO field in the PIN_FLD_TOPUP_INFO array of the called opcode's input flist (see step 3 for opcode names).

    • Automatic top-up amount

      To specify the payment amount of each automatic standard top-up, set the appropriate value in the PIN_FLD_TOPUP_AMT field in the PIN_FLD_TOPUP_INFO array of the called opcode's input flist.

    • Automatic top-up cap

      To specify the aggregate amount of automatic standard top-ups that the account can receive during an accounting cycle, set the appropriate value in the PIN_FLD_TOPUP_CAP field in the PIN_FLD_TOPUP_INFO array of the called opcode's input flist.

    • Bill unit to top up

      To specify the bill unit that contains the balance to top up, set the appropriate value in the PIN_FLD_BILLINFO field in the PIN_FLD_TOPUP_INFO array of the called opcode's input flist.

  3. Pass the information to one of these opcodes:

    • PCM_OP_CUST_COMMIT_CUSTOMER when creating accounts

    • PCM_OP_CUST_UPDATE_CUSTOMER when modifying accounts

      Note:

      Both of these opcodes call PCM_OP_CUST_SET_TOPUP, which is a wrapper opcode that calls other standard opcodes to set up or modify top-up information.

For more information, see "Setting Up Top-Up Information in an Account".

Implementing Recurring Standard Top-Ups

To implement the recurring standard top-up feature:

  1. Configure your custom client application to accept the following top-up information:

    • Type of top-up

      Set the type of top-up in the PIN_FLD_TYPE field under the PIN_FLD_TOPUP_INFO array to automatic (0), one-time (1), or recurring (2) of the called opcode's input flist.

    • Top-up amount

      Set the amount to top-up in the PIN_FLD_TOPUP_AMT field under the PIN_FLD_TOPUP_INFO array of the called opcode's input flist.

    • Maximum number of recurring top-ups

      Set the maximum number of recurring top-ups that can be made in the PIN_FLD_NUM_TOPUPS field under the PIN_FLD_TOPUP_INFO array of the called opcode's input flist.

    • Interval between recurring top-ups

      Set the interval between each recurring top-up in the following fields under the PIN_FLD_TOPUP_INFO array of the called opcode's input flist:

      • PIN_FLD_OFFSET_UNIT specifies the interval's unit: weeks (3), days (4), or month (5).

      • PIN_FLD_NUM_UNITS specifies the interval's value.

    • Currency or noncurrency resource to top-up

      Set the currency or noncurrency resource to top-up in the PIN_FLD_RESOURCE_ID field under the PIN_FLD_TOPUP_INFO array of the called opcode's input flist.

    • Payment method

      Set the payment method for recurring standard top-ups in the PIN_FLD_PAYINFO_OBJ field under the PIN_FLD_TOPUP_INFO array of the called opcode's input flist.

    • Balance group to top-up

      Set the balance group to top-up in the PIN_FLD_BAL_GRP_OBJ field under the PIN_FLD_TOPUP_INFO array of the called opcode's input flist.

  2. Pass the information to one of these opcodes:

    • PCM_OP_CUST_COMMIT_CUSTOMER when creating accounts

    • PCM_OP_CUST_UPDATE_CUSTOMER when modifying accounts

      Note:

      Both of these opcodes call PCM_OP_CUST_SET_TOPUP, which is a wrapper opcode that calls other standard opcodes to set up or modify top-up information.

  3. Run the pin_balance_transfer utility on a regular basis:

    pin_balance_transfer -standard

For more information, see "Setting Up Top-Up Information in an Account".

Implementing Manual Sponsored Top-Ups

To implement the manual sponsored top-up feature:

  1. Configure your custom client application to accept the following top-up information:

    • The POID of the account that initiates the creation or modification of the top-up configuration. Set this value in the level-one PIN_FLD_POID field of the called opcode's input flist (see step 2 for opcode names).

    • The POID of the account that will receive the top-ups (the member account). Set this value in the PIN_FLD_ACCOUNT_OBJ field in the PIN_FLD_TOPUP_INFO array of the called opcode's input flist.

    • The POID of the /topup object associated with the account that will receive the top-ups. If the account does not have a /topup object, specify the POID type. Set this value in the PIN_FLD_POID field in the PIN_FLD_TOPUP_INFO array of the called opcode's input flist.

    • Group to add member to

      To specify the sponsored top-up group to add the member account to, set the POID of the appropriate /group/topup object in the PIN_FLD_POID field in the PIN_FLD_GROUP_TOPUP_INFO array of the called opcode's input flist.

      If the object does not exist, pass the POID type.

    • Group name

      To specify the name of the sponsored top-up group, set the appropriate value in the PIN_FLD_NAME field in the PIN_FLD_GROUP_TOPUP_INFO array of the called opcode's input flist.

      If you do not specify a group name, the group will be named default.

    • Group owner

      To specify the sponsored top-up group owner account, set the POID of the owner account in the PIN_FLD_PARENT field in the PIN_FLD_GROUP_TOPUP_INFO array of the called opcode's input flist.

    • Paying balance group

      To specify the owner account's balance group to transfer top-up assets from, set the POID of the balance group in the PIN_FLD_BAL_GRP_OBJ field in the PIN_FLD_GROUP_TOPUP_INFO array of the called opcode's input flist.

    • Balances to top up

      To specify the balances to be topped up in the member account, set the IDs of the appropriate currency and noncurrency balance elements in the PIN_FLD_RESOURCE_ID fields in the PIN_FLD_GROUP_TOPUP_LIMITS array of the called opcode's input flist.

    • Balance top-up cap

      To specify the maximum amount of a balance that the owner can transfer to its members during the owner's accounting cycle, set the appropriate value in the balance's PIN_FLD_TOPUP_CAP field in the PIN_FLD_GROUP_TOPUP_LIMITS array.

      Note:

      This cap applies to the sum of all top-ups in the group, not to an individual member's top-ups. The cap should not exceed the credit limit of the paying balance group.

    • Receiving balance group

      To specify the member account's balance group to transfer sponsored top-ups to, set the POID of the balance group in the member's PIN_FLD_BAL_GRP_OBJ field in the PIN_FLD_GROUP_TOPUP_MEMBERS array of the called opcode's input flist.

    • Top-up PIN

      To specify the member's sponsored top-up PIN, set the appropriate value in the PIN_FLD_PIN field in the PIN_FLD_GROUP_TOPUP_MEMBERS array of the called opcode's input flist.

    • Top-up status

      To specify the member's sponsored top-up status, set the appropriate value in the PIN_FLD_STATUS field in the PIN_FLD_GROUP_TOPUP_MEMBERS array of the called opcode's input flist.

  2. Pass the information to one of these opcodes:

    • PCM_OP_CUST_COMMIT_CUSTOMER when creating accounts

    • PCM_OP_CUST_UPDATE_CUSTOMER when modifying accounts

      Note:

      Both of these opcodes call PCM_OP_CUST_SET_TOPUP, which is a wrapper opcode that calls other standard opcodes to set up or modify top-up information.

Implementing Automatic Sponsored Top-Ups

To implement the automatic sponsored top-up feature:

  1. Configure your custom client application to accept the following top-up information:

    • All top-up information listed in "Implementing Manual Sponsored Top-Ups".

    • Automatic top-up amount

      To specify the amount of a balance to transfer from the owner to the member during each automatic sponsored top-up, set the appropriate value in the balance's PIN_FLD_TOPUP_AMT field in the PIN_FLD_GROUP_TOPUP_LIMITS array.

      This amount applies to every member in the group.

    • Automatic top-up frequency

      To specify the number of days in the member's automatic sponsored top-up cycle, set the appropriate value in the member's PIN_FLD_TOPUP_INTERVAL field in the PIN_FLD_GROUP_TOPUP_MEMBERS array of the called opcode's input flist (see step 2 for opcode names).

      This interval applies only to the member account.

  2. Pass the information to one of these opcodes:

    • PCM_OP_CUST_COMMIT_CUSTOMER when creating accounts

    • PCM_OP_CUST_UPDATE_CUSTOMER when modifying accounts

      Note:

      Both of these opcodes call PCM_OP_CUST_SET_TOPUP, which is a wrapper opcode that calls other standard opcodes to set up or modify top-up information.

  3. Run the pin_balance_transfer utility on a regular basis:

    pin_balance_transfer [-start mm/dd/yy] [-end mm/dd/yy]
Viewing Sponsored Top-Up History

To display information about sponsored top-up transactions, configure your custom client application to call PCM_OP_PYMT_FIND_TOPUP_EVENTS to retrieve balance transfer events (/event/billing/adjustment/account objects) in which top-up transactions are recorded.

Historic sponsored top-up information can be displayed for both sponsored top-up owner accounts and member accounts:

  • Member accounts can view only the sponsored top-ups that they received.

  • Owner accounts can view all sponsored top-ups associated with their sponsored top-up groups.

To retrieve all sponsored top-up events associated with a group owner account or a member account, include the following values in the PCM_OP_PYMT_FIND_TOPUP_EVENTS input flist:

  • Account's POID in the PIN_FLD_POID field

    Note:

    This field stores the POID of the account that initiates the search. If a POID type rather than an actual POID is provided, an actual balance group POID must be set in the flist's PIN_FLD_BAL_GRP_OBJ field.

  • No value in these fields:

    • PIN_FLD_BAL_GRP_OBJ

      Note:

      If no account POID is provided, a balance group POID must be provided. In such cases, the opcode retrieves top-up events associated only with the specified balance group.

    • PIN_FLD_REASON_ID

    • PIN_FLD_REASON_DOMAIN_ID

If an owner account has multiple sponsored top-up groups, retrieve sponsored top-up events related only to one group by including the following values in the PCM_OP_PYMT_FIND_TOPUP_EVENTS input flist:

  • Group owner account's POID in the PIN_FLD_POID field

  • Paying balance group's POID in the PIN_FLD_BAL_GRP_OBJ field

  • No value in these fields:

    • PIN_FLD_REASON_ID

    • PIN_FLD_REASON_DOMAIN_ID

By default, PCM_OP_PYMT_FIND_TOPUP_EVENTS retrieves all sponsored top-up debit and credit adjustment events associated with the initiating account. Thus, if a sponsored top-up group owner account initiates the search, the opcode retrieves two events for each top-up:

  • An event for debiting the top-up amount from the owner's paying balance group

  • An event for crediting the top-up amount to a member's receiving balance group

To limit the search to debit or credit adjustment events, include the appropriate reason ID and reason domain ID in the PIN_FLD_REASON_ID and PIN_FLD_REASON_DOMAIN_ID fields of the opcode's input flist.

Note:

If you create custom reason and reason domain IDs for sponsored top-up events, PCM_OP_PYMT_FIND_TOPUP_EVENTS returns events associated with all the IDs unless you limit the search to specified IDs.

About Transferring Sponsored Top-Ups from Debit Balances

To perform a sponsored top-up, PCM_OP_BILL_TRANSFER_BALANCE must transfer assets from a debit balance in a group owner account to a debit or credit balance in a member account. By default, however, this opcode transfers assets only from credit balances. To enable the opcode to transfer assets from a debit balance, the PIN_FLD_VERIFY_BALANCE field in its input flist is set to PIN_BOOLEAN_FALSE by PCM_OP_PYMT_TOPUP.

Note:

If this field is not set (default) or is set to PIN_BOOLEAN_TRUE, the opcode cannot transfer assets from debit balances.

Setting an Account's Sponsored Top-Up Member Status and PIN

If an account is a member of a sponsored top-up group, its group status and top-up PIN are set as follows:

  • When an owner account initiates adding a member to the group, the member's group status and PIN are set according to the information in the PCM_OP_CUST_SET_TOPUP input flist. If member status is not specified in the flist, it is set to active.

  • When a member account initiates adding itself to a group, the member's group status is set to inactive and the PIN is set to NULL no matter what values are provided for those items in the input flist. After the member is added to the group, the group owner must activate the member's member and sets its top-up PIN.

  • When a member account initiates a modification of its sponsored top-up settings after being added to a group, its group status is reset to inactive. This occurs even if the modification is not related to member status. The group owner must then reactivate the member.

Activating Sponsored Top-Up Group Members

To receive sponsored top-ups, a member's group status must be active. By default, only groups owners can activate a member. To enable members to activate themselves, customize the PCM_OP_CUST_POL_PREP_TOPUP policy opcode.

To activate members whose group status is inactive or closed:

  1. Use your custom client application to call PCM_OP_CUST_SET_TOPUP.

  2. Set the member's PIN_FLD_STATUS field in the MEMBERS array of the opcode's input flist to the value associated with the PIN_STATUS_ACTIVE status in the BRM_home/include/ops/pcm.h header file.

Inactivating Sponsored Top-Up Group Members

A member whose group status is inactive can use any outstanding topped-up credit in its topped-up balance group, but it cannot receive any more top-ups from the group until its member status is reactivated. In addition, it cannot join another sponsored top-up group.

To inactivate a member's group status:

  1. Use your custom client application to call PCM_OP_CUST_SET_TOPUP.

  2. Set the member's PIN_FLD_STATUS field in the MEMBERS array of the opcode's input flist to the value associated with the PIN_STATUS_INACTIVE status in the BRM_home/include/ops/pcm.h header file.

    Note:

    You can also inactivate sponsored top-ups by changing the status of the member account to inactive. To change the status of an account, see "Changing Account and Service Status" in BRM Managing Customers.

To inactivate the group status of every member in a group, change the status of the sponsored top-up group owner account to inactive.

When a group owner account is inactive, the members of its sponsored top-up groups can use any outstanding topped-up credit in their topped-up balance groups, but they cannot receive any more top-ups from the group until the owner account is reactivated, and they cannot join another sponsored top-up group.

Setting Sponsored Top-Up Member PINs

By default, only groups owners can set a member's PIN.

To assign a top-up PIN to a member:

  1. Use your custom client application to call PCM_OP_CUST_SET_TOPUP.

  2. Set the member's PIN_FLD_PIN field in the MEMBERS array of the opcode's input flist to the appropriate string value.

    Note:

    • By default, top-up PINs do not have to be unique. Members in the same group and in different groups can have the same top-up PIN.

    • To enable members to set their own PINs, customize the PCM_OP_CUST_POL_PREP_TOPUP policy opcode.

Offering Discount Incentives with Top-Ups

You can offer customers discount incentives whenever they top up an account balance by a specified amount. For example, you can offer 20 free peak minutes whenever a customer makes a $50 top-up.

To offer top-up discount incentives:

  1. Set up the discount in PDC or Pricing Center.

  2. Configure the PCM_OP_PYMT_POL_PURCHASE_DEAL policy opcode to validate the discount.

    By default, this policy opcode is an empty hook provided to facilitate customization. You can customize it to apply discounts to account balances when they are topped up. For example, this policy opcode might grant 60 minutes of usage for every $50 top-up.

    PCM_OP_PYMT_POL_PURCHASE_DEAL is called by PCM_OP_PYMT_TOPUP.

Suspending and Recycling Payments

This section describes the opcodes used for payment suspense management.

How BRM Tracks Suspended Payments

All payments and payment reversals contain a transaction ID (TRANS_ID field), which is a unique identifier that enables you to track each payment and reversal in BRM:

  • For payments, the transaction ID identifies the payment transaction from the third-party payment processor. If a payment is submitted to BRM without a transaction ID, one is assigned to it.

  • For reversals, the transaction ID is generated by BRM.

In addition to having a transaction ID, payments and reversals have another ID that is used to track all actions performed on a specific payment: a subtransaction ID (SUB_TRANS_ID field) for payments, and a paytransaction ID (PAYMENT_TRANS_ID field) for reversals. These ID values are used to find all payments and reversals that occur due to the recycling of an original payment.

  • The SUB_TRANS_ID value of an original (never-recycled) payment is NULL.

  • The SUB_TRANS_ID value of a recycled payment is equal to the transaction ID of its original payment.

  • The PAYMENT_TRANS_ID value of a payment reversal is equal to the transaction ID of the payment it reversed.

In the example shown in Figure 20-1, a $3000 payment is suspended when it first arrives in BRM so that it can be posted to individual accounts within the corporation. The original payment is represented in white.

The payment analyst first partially distributes the original suspended payment to two accounts. The first distributed payment is for $1000 to Account A and the second is for $700 to Account B. The remaining $1300 is resuspended. The results of this operation are represented in Phase 1.

Later, the payment analyst realizes that the distributed payment made to Account B was erroneous and puts the $700 payment back into suspense, leaving $1000 in Account A and $2000 in the suspense account. The results of this operation are represented in Phase 2.

Figure 20-1 Suspended Payment Distribution Example

Description of Figure 20-1 follows
Description of "Figure 20-1 Suspended Payment Distribution Example"

In this figure, all payments except the original payment are recycled payments. Notice that:

  • Both distributed payments have the same subtransaction IDs (s1). The SUB_TRANS_ID value is the same as the TRANS_ID value of the original payment.

  • All of the recycled payments have SUB_TRANS_ID values that match the original payment's TRANS_ID values.

  • Each reversal has a PAYMENT_TRANS_ID value that is equal to the TRANS_ID value of the payment it reversed.

When an original suspended payment is applied to a customer account, the following operations occur:

  1. The suspended payment is reversed, and an /event/billing/reversal object is created. The reversal object's PAYMENT_TRANS_ID value is equal to the TRANS_ID value of the suspended payment.

  2. A new payment (event/billing/payment/pay_type object) is applied to the customer account and contains the following information:

    • The original suspended payment's details, including a value for any amount remaining in suspense.

    • A SUB_TRANS_ID value that is equal to the suspended payment's TRANS_ID value.

  3. If an amount remains in suspense, a new suspended payment is created for that amount; the original payment is not adjusted with a new amount. Instead, the new suspended payment receives a SUB_TRANS_ID value that is equal to the original payment's TRANS_ID value.

    Likewise, when a suspended payment is partially allocated to one or more accounts, and then an allocated payment is resuspended, the current suspended payment that was partially allocated is reversed and a new suspended payment containing the new amount is created.

    Note:

    An original payment does not have to be a suspended payment. For example, if a payment was posted successfully to a customer account when it was received by BRM, it is an original payment. If it is later suspended and then reposted to customer accounts, both the suspended payment and the posted payment will have SUB_TRANS_ID values that match the TRANS_ID value of the original successful payment as shown in Figure 20-2:

Figure 20-2 SUB_TRANS_ID of a Suspended Payment

Description of Figure 20-2 follows
Description of "Figure 20-2 SUB_TRANS_ID of a Suspended Payment"

Customizing Payment Suspense

You can customize payment suspense in several ways. See the following topics:

See the chapter about payments in BRM Opcode Guide for more information.

Customizing Payment Suspense Validation

The PCM_OP_PYMT_POL_VALIDATE_PAYMENT policy opcode validates payments to determine whether they can be successfully posted or whether a failed, unconfirmed payment needs reversal. If automatic write-off reversals are enabled, it also determines whether BRM should perform a write-off reversal.

In default implementations, BRM considers two questions when determining whether a payment should be suspended:

  • Is the account number present and valid?

  • Is the account closed?

By default, the bill number is not initially used to suspend payments. It is used only when the account number is missing.

A payment is suspended in the following situations:

  • The account is closed.

  • The account number is missing and the bill number is missing.

  • The account number and the bill number are invalid.

  • The account number does not match the account number from the bill.

A payment is posted if the account is not closed and the following is true:

  • The account number is present and valid. If the bill number is missing, the payment is posted at the account level.

  • The account number is missing but the bill number is present and valid. Such payments are posted at the bill level.

To have Payment Tool mark these payments as suspended, see "Customizing Suspense Criteria for Payment Tool".

You can broaden this scope by customizing the PCM_OP_PYMT_POL_VALIDATE_PAYMENT policy opcode to perform validation using additional criteria (for example, customer segment, payment amount, and so on). BRM uses these criteria to determine whether the payment validation logic should mark a payment for suspense.

Note:

If you include additional criteria in the PCM_OP_PYMT_POL_VALIDATE_PAYMENT policy opcode that is not already part of the objects created by payment processing, you must also extend these objects by adding these fields so that the object records all the criteria considered by payment validation.

If neither the bill number nor bill POID was submitted with the payment, you can configure BRM to find the bill based on the due amount.

See the chapter about payments in BRM Opcode Guide for more information.

Customization Example: Suspending Large Payments

As an example, if you want a payment analyst to always examine suspiciously large cash payments or cash payments that appear to arrive from the Internet, you can customize BRM to suspend any payments that meet these conditions. If a cash payment is suspiciously large, there may be a customer error or recording error that must be investigated. Because the Internet is not a likely source of cash payments, you may want to obtain extra confirmation on how this payment was made.

This type of customization includes the following tasks:

  • Modify the PCM_OP_PYMT_POL_VALIDATE_PAYMENT policy opcode to include logic that checks the PIN_FLD_PAYMENT_TYPE field to determine if this is a cash payment and also checks PIN_FLD_CHANNEL_ID to see whether the payment was made over the Internet. If both conditions are met, have the opcode set PIN_FLD_STATUS to PIN_PYMT_SUSPENSE.

  • Also modify the PCM_OP_PYMT_POL_VALIDATE_PAYMENT policy opcode to include logic that checks the PIN_FLD_AMOUNT field to see whether the payment amount is greater than the amount you establish as the threshold for suspiciously large payments (for example, $10,000). If this is a cash payment and the payment amount exceeds the threshold, have the opcode set PIN_FLD_STATUS to PIN_PYMT_SUSPENSE.

Customization Example: Threshold for Suspending Payments

You can customize the PCM_OP_PYMT_POL_VALIDATE_PAYMENT policy opcode to enforce business practices related to suspense. For example, if you find that having payment analysts review suspended payments for very small amounts costs you more than the payments are worth, you can customize BRM so that it does not move any payment of less than a certain amount into the payment suspense account.

To create a suspense threshold, you customize the opcode to check the PIN_FLD_AMOUNT field to see whether the payment amount is less than the threshold amount (for example, $1). You check this condition for any payment whose status is set to PIN_PYMT_SUSPENSE. For each payment that meets these conditions, you set the account POID to a special account you set up for this type of unallocatable payment. You also set PIN_FLD_STATUS to PIN_PYMT_SUCCESSFUL so that PCM_OP_PYMT_COLLECT can post the payment.

Note:

When you implement any of the customizations just discussed, you modify the PCM_OP_PYMT_POL_VALIDATE_PAYMENT policy opcode. This opcode validates only externally initiated payments; it does not validate BRM-initiated payments. Therefore, none of the customizations you implement through this opcode affect BRM-initiated payments.

Customization Example: Finding Unconfirmed Payments

In the case of failed unconfirmed payment, if the payment processor is not able to send a transaction ID with each payment, you can modify the PCM_OP_PYMT_POL_VALIDATE_PAYMENT policy opcode to find the original unconfirmed payment by using other payment properties that are sent from the payment gateway, such as the original unconfirmed payment amount. When the original unconfirmed payment is found, the item object to which the payment was applied can be loaded into the input flist for the PCM_OP_PYMT_APPLY_FEES opcode.

Note:

If you used failed payment properties to locate the payment, you must also update the /event/billing/payment/failed object to contain the same properties that you are using to locate the original unconfirmed payment.

Customization Example: Error Handling

You can modify the PCM_OP_PYMT_POL_VALIDATE_PAYMENT policy opcode to handle errors that occur because the original unconfirmed payment cannot be found or the transaction IDs do not match.

Customizing Suspended Payment Distribution

The PCM_OP_PYMT_POL_SUSPEND_PAYMENT policy opcode enables you to define custom rules for handling payments that are being guided into suspense. For example, you can modify this policy opcode to track the number of times the same payment is guided back to suspense after being applied to the wrong customer account.

In addition, if your company processes distributed payments, you can implement rules to distribute a payment directly to the proper accounts, without first saving the payment to the suspense account. For example, by using the account number associated with the original payment, the original payment amount, and the account number associated with each subpayment amount, you can automatically divide the payment into distributed payments and allocate them to the designated accounts.

For multiple suspense accounts, the PCM_OP_PYMNT_POL_SUSPEND_PAYMENT policy opcode must be modified to select a payment suspense account that matches the criteria specified while creating the account. Otherwise, the policy opcode selects a payment suspense account that matches the login schema.

Customizing Payment Failure Reason Codes

To customize payment failure reason codes, use the PCM_OP_PYMT_POL_CHARGE policy opcode. This policy opcode provides the ability to map the online and offline payment result to the payment status and the reason IDs defined in the /strings object.

In the output flist PIN_FLD_PAYMENT_REASONS array, the array of PIN_FLD_REASON_ID fields contains the failure reasons sent by the payment processor. You can configure this policy opcode to apply fees for failed credit card and direct debit transactions based on the reason for failure.

The input flist contains a results array for a payment batch, including reasons for payment failures.

The output flist contains the payment method, transaction ID, and an array of reason IDs for failed payments.

Customizing Payment Tool

The procedures in this section describe how to add a cash reversal batch to Payment Tool and how to extend Payment Tool to automatically suspend payments that have a missing bill number.

Adding a Cash Reversal Batch

You can add a cash reversal batch to Payment Tool to handle any cash payments that were posted incorrectly and must be reversed from your BRM system. For example, if the currency a customer used to make a payment was later found to be counterfeit, you can remove the payment. This restores the customer's previous account balance and removes the payment from your company's G/L system.

The /event/billing/reversal/cash storable class exists in the BRM database; therefore, there is no need to create one. You only need to add the cash reversal entry to the /config/paymenttool object.

Note:

When you install BRM, a default /config/paymenttool object is created from data in the init_objects.source file.

  1. Use the PCM_OP_WRITE_FLDS opcode to add the cash reversal entry to the /config/paymenttool storable class. Call the opcode using flag 32. For example:

    0  PIN_FLD_POID         POID [0] 0.0.0.1 /config/paymenttool 13748 0
    0  PIN_FLD_ACCOUNT_OBJ  POID [0] 0.0.0.1 /account 1 0
    0  PIN_FLD_DESCR        STR [0] "US_EN paymentTool pymnt type configuration locale" 
    0  PIN_FLD_HOSTNAME     STR [0] "-" 
    0  PIN_FLD_NAME         STR [0] "PaymentTool payment Types: Default" 
    0  PIN_FLD_PROGRAM_NAME STR [0] "-" 
    0  PIN_FLD_VALUE        STR [0] "" 
    0  PIN_FLD_VERSION      STR [0] "" 
    0  PIN_FLD_PAY_TYPE     ARRAY [10011] allocated 2, used 2 
    1     PIN_FLD_NAME               STR [0] "Cash" 
    1     PIN_FLD_PAYMENTTOOL_FIELDS ARRAY [0] allocated 4, used 4 
    2        PIN_FLD_BATCH_TYPE         INT [0] 1 
    2        PIN_FLD_COLUMN_NAME        STR [0] "Receipt Date" 
    2        PIN_FLD_FIELD_NAME         STR [0] "PIN_FLD_EFFECTIVE_T" 
    2        PIN_FLD_PURPOSE            INT [0] 0 
    1     PIN_FLD_PAYMENTTOOL_FIELDS ARRAY [1] allocated 4, used 4 
    2        PIN_FLD_BATCH_TYPE         INT [0] 1 
    2        PIN_FLD_COLUMN_NAME        STR [0] "Receipt No." 
    2        PIN_FLD_FIELD_NAME         STR [0] "PIN_FLD_REASON_CODE" 
    2        PIN_FLD_PURPOSE             INT [0] 0
    

    Note:

    • The PIN_FLD_BATCH_TYPE value determines the batch type: 0 indicates a payment batch and 1 indicates a reversal batch. In this example, PIN_FLD_BATCH_TYPE is set to 1 for reversal.

    • The PIN_FLD_PURPOSE value determines the field type: 0 indicates the field is read-only and 1 indicates that data can be entered into the field. In this example, the Receipt Date and Reason Code columns in the reversal batch are read-only.

  2. Stop and restart the CM.

    All changes you make in /config/paymenttool are reflected in the Payment Tool UI when you restart BRM.

Customizing Suspense Criteria for Payment Tool

When you submit payments by using Payment Tool, payments that have a valid account number and a missing bill number are not marked for suspense by default.

To enable Payment Tool to return such payments as suspended, customize the fm_pymt_pol_validate_payment_bill function in the PCM_OP_PYMT_VALIDATE_PAYMENT opcode. Use the &validation_result value to set the PIN_FLD_STATUS value.

Handling Custom Payment Methods

If you create custom payment methods for your BRM system, you must customize Payment Suspense Center to handle them. This overview procedure describes how to create custom storable classes and fields and enable Payment Center to handle them.

For detailed information on creating custom storable classes and fields, see "Creating Client Applications by Using Java PCM" and "Creating Custom Fields and Storable Classes" in BRM Developer's Guide.

  1. Complete the following tasks by using Storable Class Editor:

    1. Create your storable classes and fields in the Java PCM package.

    2. Create source files for your custom fields.

      Note:

      Storable Class Editor creates a C header file called cust_flds.h, a Java properties file called InfranetPropertiesAdditions.properties, and a Java source file for each custom field.

  2. In the directory where Storable Class Editor created the Java source files, compile the source files:

    javac -d . *.java
    
  3. Package the new storable class files into a JAR file. For example:

    jar cvf customfields.jar *.class
  4. Copy the contents of the InfranetPropertiesAdditions.properties file and paste it into the Payment Suspense Center Infranet.properties file. By default, this file is located in:

    C:\Program Files\Portal Software\PymtSuspCenter\PaymentCenter
    
  5. Append the location of the JAR file to the PAYCTRCP environment variable path. For example:

    ;.;C:\Program Files\Portal Software\PymtSuspCenter\customfields.jar;
    

About the Suspense Account

When BRM creates the payment suspense account, PCM_OP_CUST_POL_PREP_NAMEINFO first prepares the contact information for validation and then determines whether Payment Suspense Manager is enabled. If it is enabled and the account being checked is the payment suspense account, this opcode retrieves the POID of the /config/psm object if that object exists. BRM references the /config/psm object to locate the payment suspense account whenever it suspends a payment or you correct a payment.

The payment suspense account POID is then passed to PCM_OP_CUST_SET_NAMEINFO. This opcode stores the account POID in the /config/psm object.

Suspending Payments during Payment Processing

During payment processing, PCM_OP_PYMT_COLLECT calls PCM_OP_PYMT_VALIDATE_PAYMENT, to determine the status of the payment records. (For information about PCM_OP_PYMT_COLLECT, see "Collecting Payments".)

When PCM_OP_PYMT_VALIDATE_PAYMENT receives a payment to validate, it determines whether the payment should be suspended and prepares it for posting by enriching the flist with any missing information.

It begins by evaluating the input flist to determine whether it contains the channel ID for the payment. If not, it gets the channel ID from the /config/ach object and adds it to the flist.

Then, PCM_OP_PYMT_VALIDATE_PAYMENT calls PCM_OP_PYMT_POL_VALIDATE_PAYMENT to validate the payment and further enrich the flist with any missing payment information.

After PCM_OP_PYMT_VALIDATE_PAYMENT receives the results from PCM_OP_PYMT_POL_VALIDATE_PAYMENT, it returns the flist to PCM_OP_PYMT_COLLECT for use when the payment is posted.

Flags are not used directly by PCM_OP_PYMT_VALIDATE_PAYMENT. They are passed in from PCM_OP_PYMT_COLLECT for PCM_OP_PYMT_SELECT_ITEMS. For example, Payment Tool can set the PCM_BILLFLG_DEFER_ALLOCATION flag to indicate which payments should be left unallocated.

Note:

When you submit payments by using Payment Tool, payments that have a valid account number but a missing bill number are not marked for suspense by default.

How Payments Are Recycled to and from Suspense

PCM_OP_PYMT_RECYCLE_PAYMENT removes a payment from a source account and posts it to a target account. It is called when one or more payments in Payment Center are submitted to the BRM database. This opcode is called when a single payment or a list of distributed payments is transferred between the payment suspense account and one or more customer accounts.

Note:

It is not recommended to have more than one payment suspense account in the /config/psm object.

For account payment to multiple bill units, there can be more than one event generated for an individual payment. Therefore, the output flist of PCM_OP_PYMT_RECYCLE_PAYMENT shows all the payment events.

When a payment is recycled from suspense to a customer account, the input flist generated for the submission includes the corrected account number, corrected bill number, and the transaction ID of the original payment. It can also contain other corrected information if you customized BRM to include additional validation criteria.

When a transaction is opened, PCM_OP_PYMT_RECYCLE_PAYMENT handles all of the activities required to move each payment in the CHARGES array from the source account to the target account. The transaction ID is recorded in all the event objects created when this opcode processes a payment.

PCM_OP_PYMT_RECYCLE_PAYMENT validates that the source account is the account to which the payment was posted and that the destination account is the payment suspense account. If both requirements are true, the payment is recycled to suspense.

The CHARGES array contains two fields that determine the direction of the transfer:

  • PIN_FLD_EVENT_OBJ: This field identifies the payment event. The event, in turn, identifies the source account, the account that owns the payment. This is the account from which the opcode transfers payments.

  • PIN_FLD_ACCOUNT_OBJ: This field identifies the target account, the account to which the opcode transfers payments.

For example, if the account referenced in PIN_FLD_EVENT_OBJ is the suspense account and the account referenced in PIN_FLD_ACCOUNT_OBJ is a customer account, the opcode distributes all or part of the suspended payment to the customer account.

If a payment is being moved from suspense, the PIN_FLD_EVENT_OBJ field establishes the payment suspense account as the source account, and the PIN_FLD_ACCOUNT_OBJ field contains one or more POIDs of valid customer accounts. If a payment is being moved to suspense, the PIN_FLD_EVENT_OBJ field establishes a valid customer account as the source account, and the PIN_FLD_ACCOUNT_OBJ field contains the POID of the payment suspense account.

The source and target accounts, combined with the number of payments in the CHARGES array, determine the operation that PCM_OP_PYMT_RECYCLE_PAYMENT performs.

PCM_OP_PYMT_RECYCLE_PAYMENT performs the following operations when recycling payments:

  1. Opens a transaction.

  2. Determines the direction of the payment recycling: to or from the payment suspense account. The transfer direction is determined by the active payment's account POID and the target account POID.

    • Determines if multiple distributed payments are being handled.

    • Checks that the currency is the same for every charges element.

    • If it is returning an entire distribution to suspense, calls PCM_OP_PYMT_RECYCLED_PAYMENTS_SEARCH to retrieve the active suspended payment information, including the amount remaining in the suspended payment after recycling, and adds it to the CHARGES array.

  3. Chooses a course of action based on the source account/target account combination plus the information in the CHARGES array.

  4. Calls PCM_OP_PYMT_COLLECT to apply the payments to the target accounts, prepares the payment batch, and enriches the PCM_OP_PYMT_COLLECT input flist with the following information:

    • The total charge amount.

    • Total reversal amount, for posted payments that are being suspended.

    • Total original payment amount, for payments that are being posted from the payment suspense account to a customer account.

    PCM_OP_PYMT_COLLECT, in turn, calls PCM_OP_PYMT_VALIDATE_PAYMENT to validate the information in the CHARGES array. If an invalid scenario exists, the payment is guided to suspense.

    Note:

    For payments guided to suspense due to validation failures, PCM_OP_PYMT_RECYCLE_PAYMENT rolls back the entire transaction after PCM_OP_PYMT_COLLECT completes.

  5. Prepares the reversal batch, creating new elements and setting a new reason code.

    If PCM_OP_PYMT_RECYCLE_PAYMENT is being called for a distribution and the total of the charges in the input flist does not equal the amount to be distributed, the opcode determines whether the input flist specifies an amount to be placed in suspense.

    • If the input flist does not specify an amount to be placed in suspense, the opcode posts the remaining amount to the suspense account.

    • If the input flist specifies an amount to be placed in suspense, the opcode generates an error.

  6. Calls PCM_OP_PYMT_COLLECT to perform these tasks:

    • Create the payment batch.

    • Create a suspended payment if an amount remained in the suspended payment after it was applied to one or more accounts.

    • Update the /event/billing/payment/pay_type object with the SUB_TRANS_ID value specified in the PIN_FLD_CHARGES array of the flist.

  7. If the payment batch was successful, updates the PCM_OP_BILL_REVERSE input flist with the following information:

    • The reason code for the reversal

    • The PAYMENT_TRANS_ID value

  8. Calls PCM_OP_BILL_REVERSE to create the reversal batch.

    PCM_OP_BILL_REVERSE updates the /event/billing/reversal/pay_type object with the PAY_TRANS_ID, the POID of the payment suspense account, and the reversal total.

    If PCM_OP_PYMT_COLLECT fails or if any information is invalid, PCM_OP_PYMT_RECYCLE_PAYMENT rolls back the entire transaction, leaving the suspended payment in its original state.

  9. Records the success or failure of the entire operation in the PIN_FLD_RESULTS field of the output flist.

Understanding Payment Recycling

Payment recycling is a transactional process consisting of two sequential operations:

  1. Reversing a payment from a source account.

  2. Applying a payment to a target account.

Payment recycling occurs each time you move a payment from a customer account to the payment suspense account or from the payment suspense account to a customer account. When a payment is recycled, the current payment is reversed, and all of the payment information, except for the original payment date, is transferred to the new recycled payment.

BRM uses the PIN_FLD_STATUS field of a payment to validate payments before they are recycled and submitted to an account. The status code is returned by Payment Center and can be configured.

Payments can be recycled any number of times; however, each recycled payment can be traced back to only one original payment. BRM uses the payment's transaction ID and subtransaction ID to track their origin and descendants.

About Original Payments

An original payment is the first instance of a payment that is saved to BRM, either through Payment Tool or a payment processor. Original payments can be saved initially to the suspense account or to a customer account. The distinguishing characteristic of an original payment is that it has never been recycled.

Because an original payment is the first instance of a payment, it does not have a subtransaction ID, which is an ID used to trace a recycled payment back to its original payment.

An original payment can be the ancestor of one or more recycled payments, but a recycled payment can be traced back to only one original payment. Both suspended payments and those posted in customer accounts can be original payments.

About Payment Transfer Direction and Verification

When BRM receives a distribution list from Payment Center, it determines the direction of the payment transfer: from the payment suspense account to a customer account, or to the payment suspense account from a customer account.

If a payment is being moved from suspense, BRM establishes the payment suspense account as the source account, and one or more customer accounts as the destination. If a payment is being moved to suspense, BRM establishes a valid customer account as the source account, and the payment suspense account as the destination.

Before recycling a payment, BRM verifies that there are no conditions present that prevent the transfer. These conditions include:

  • The currency for the source account and all target accounts is different.

  • The source and target accounts are both customer accounts.

  • Multiple suspended payments are recycled in the same operation.

  • You attempt to partially suspend a payment originally posted to a customer account. You can only perform this action if you suspend the entire payment.

  • You attempt to distribute a failed payment from the suspense account into a customer account.

  • You attempt to return a distributed payment from a customer account to the suspense account, but the suspended payment is also a failed payment. This can happen when you distribute a suspended payment to customer accounts and, afterward, the payment fails for financial reasons (for example, the bank will not honor the check). In this case, you cannot return the distributed payment to suspense.

About Recycling Payments from Suspense

When you post a suspended payment to a customer account, the following operations occur if validation and transfer verification are successful:

  1. The suspended payment is reversed (an /event/billing/reversal object is created).

  2. The payment item for the suspended payment is closed.

  3. A recycled payment is posted in the customer account. The payment status reflects that the payment was successfully recycled.

  4. Bills, bill items, or both in the account might be closed, depending on the payment allocation level.

  5. A new suspended payment is created for any unallocated amount (partially allocated payments).

You do not have to fully allocate a suspended payment. If you partially allocate a suspended payment and an amount remains in suspense, you can apply the remaining amount to any account at any time.

About Recycling Payments to Suspense

When you suspend a payment that has been posted in a customer account, the following operations occur if validation is successful:

  1. The posted payment is reversed (an /event/billing/reversal object is created).

  2. Any accounts receivable items (/item/payment) that were previously closed by the payment are reopened.

  3. A recycled payment is created in the payment suspense account. The payment status reflects that the payment was successfully recycled.

  4. A new billable item for the recycled suspended payment is created.

How Payment Reversals Work with Suspense and Recycling

Payments are reversed in BRM for a variety of reasons, the most common of which is that the funds for a payment are never actually deposited (for example, when a check does not clear). Payments also can be reversed as part of the suspense process.

When a payment is reversed, two things happen:

  • Any bills or items previously closed by the payment are reopened.

  • The payment is deactivated in the BRM system.

There are three types of reversals in BRM. The first two, indirect reversal and reversal to remove an unallocatable suspended payment, are related to the suspense process. The third, direct reversal, is not.

  • Reversals that occur indirectly during the recycling process

    Indirect reversals occur when you transfer a suspended payment to a customer account or from a customer account to suspense. With an indirect reversal, the payment is removed from the source account and moved to the target account, resulting in a complete reversal of the payment in the source account so that the payment information can be transferred to the destination account as a recycled payment. If the payment being recycled had been posted in a customer account, any bills and items that were closed due to the payment are reopened.

    Indirect reversals are assigned a G/L ID of 113, placing the payment amount in a special G/L bucket so that you can keep a separate record of these reversals.

  • Reversals that occur when you remove a payment as unallocatable

    If a suspended payment cannot be fixed but you want to track revenue for these payments and get reports on how much unallocatable revenue you have, you can remove them from suspense as unallocatable. When you do this, BRM reverses the payment in the payment suspense account and assigns it to a special G/L ID bucket. These reversals are rare in BRM. Even though they are part of suspense, they occur outside of the recycling process.

  • Reversals that you perform directly by using Payment Tool or a third-party application

    Direct reversals occur when you use Payment Tool or a third-party application to reverse a payment that was recorded in the BRM database but never actually deposited. Direct reversals are the most frequent type of reversal in BRM, and they occur outside of the suspense and recycling processes.

    Direct reversals reverse an active payment completely and reopen any bills and items so the payment can be made again. Unlike reversals that occur during recycling, direct reversals are not initiated by the creation of a new recycled payment.

About Directly Reversing Payments from BRM

Payment reversals are necessary when a payment is recorded in the BRM database but the payment is not deposited. You create payment reversal batches by using Payment Tool.

When you have Payment Suspense Manager enabled, payments may be reversed due to payment recycling, which is different from directly reversing the payment from the BRM database. Reversals that occur due to recycling happen automatically, and the funds are transferred from a source account to a target account: they are not removed completely from BRM.

The type of payment reversal discussed here is different from recycled payment reversals. Here, you manually reverse a payment to remove it from the system. A recycled payment reversal is a consequence of transferring a payment to a target account.

The following restrictions apply when reversing payments from BRM:

  • You cannot directly reverse recycled payments: you can reverse only original (nonrecycled) payments with a SUB_TRANS_ID value of NULL. Therefore, when creating the payment reversal batch for a payment that entered the database as suspended, you must identify the original suspended payment rather than the active recycled payment. When the reversal batch is submitted to BRM, all active recycled payments that are descended from the original payment will be internally reversed.

  • When directly reversing a payment, you can reverse only original payments. If you reverse an original suspended payment, BRM reverses all of the active recycled payments that were distributed to customer accounts from that payment.

Retrieving Recycled Payments

PCM_OP_PYMT_RECYCLED_PAYMENTS_SEARCH retrieves payment information such as the payment amount, transaction ID, subtransaction ID, account and bill number, payment types, and payment status. If you specify that more information be returned, this opcode can return additional payment information such as the action owner and the date suspended.

PCM_OP_PYMT_RECYCLED_PAYMENTS_SEARCH is called by:

  • Payment Center to provide additional information on the payments returned by a search (for example, allocated amount and unallocated amount).

  • PCM_OP_BILL_REVERSE when it reverses a payment that was posted to the suspense account when it entered the BRM database. This opcode uses PCM_OP_PYMT_RECYCLED_PAYMENTS_SEARCH to find all active payments associated with the original suspended payment so that those payments also can be reversed. For more information, see "How Suspended Payments Are Reversed".

  • PCM_OP_PYMT_RECYCLE_PAYMENT when it returns an entire set of distributed payments to the suspense account.

As input, PCM_OP_PYMT_RECYCLED_PAYMENTS_SEARCH receives the transaction ID of the payment it is to search for. It also receives an optional PIN_FLD_RESULTS array, which, with the PCM_OP_FLAG_READ_RESULT flag, determines the type of information returned by the opcode.

PCM_OP_PYMT_RECYCLED_PAYMENTS_SEARCH performs the following operations when searching for payments:

  1. Verifies that the transaction ID in the PIN_FLD_TRANS_ID field is for an original suspended payment. To do this, the opcode checks the PIN_FLD_SUB_TRANS_ID field. If this field is not NULL, the payment is not an original payment, and the opcode returns an error.

  2. Searches for all payments whose subtransaction ID matches the PIN_FLD_TRANS_ID field of the payment in the input flist.

  3. Checks to see whether the PIN_FLD_RESULTS array in the input flist and the PCM_OP_FLAG_READ_RESULT flag are present. The opcode returns payment information based on these presence of the flag and array, as follows:

    • If neither the flag nor the array is present, the opcode returns only the fields in the output flist.

    • If the flag is present, the opcode returns all the fields in the /event/billing/payment object.

    • If the flag is not present but the array is, the opcode returns the fields in specified in the PIN_FLD_RESULTS array plus the payment information fields normally included in the output flist.

    • If the both the flag and array are present, the opcode ignores the array and returns all the fields in the /event/billing/payment object.

PCM_OP_PYMT_RECYCLED_PAYMENTS_SEARCH does not retrieve payment states for payments that have been reversed and are no longer active. If the search results are NULL, PCM_OP_PYMT_RECYCLED_PAYMENTS_SEARCH searches for reversal events related to a suspended payment. If a reversal event is found, the suspended record is filtered and not returned.

How Suspended Payments Are Reversed

PCM_OP_BILL_REVERSE prepares information for PCM_OP_BILL_REVERSE_PAYMENT to perform reversals. PCM_OP_BILL_REVERSE reverses payments during the following payment suspense operations:

  • A payment is recycled to or from suspense.

  • A suspended payment is removed from BRM as unallocatable.

Payments can also be reversed directly from BRM by submitting a payment reversal batch from Payment Tool. For information on how direct reversals are performed, see "Reversing Payments".

How Payments Are Reversed During Recycling

If PCM_OP_BILL_REVERSE is called from PCM_OP_PYMT_RECYCLE_PAYMENT, the reversal is due to recycling, and PCM_OP_BILL_REVERSE performs the following operations:

  1. Assigns the reversal TRANS_ID value for each recycled payment.

  2. Opens a transaction and checks the appropriate /config/business_params object to verify that Payment Suspense Manager is enabled.

  3. Calls PCM_OP_BILL_REVERSE_PAYMENT to perform the reversal and create the associated objects in the database. For each /event/billing/reversal object created, PIN_FLD_PAYMENT_TRANS_ID is set to the transaction ID of the recycled payment. This opcode populates the reversal flist with each recycled payment's TRANS_ID value.

  4. Populates the payment batch with the sum of the reversal flist.

  5. If the reversal was performed as part of recycling multiple distributed payments back into suspense, returns the recycled payments' reversal information in the PIN_FLD_MULTI_RESULTS array.

How Payments Are Removed As Unallocatable

PCM_OP_BILL_REVERSE performs the following operations to remove payments from BRM as unallocatable:

  1. Assigns the reversal event a TRANS_ID value.

  2. Opens a transaction and checks the appropriate /config/business_params object to verify that Payment Suspense Manager is enabled.

  3. Checks to see whether the following criteria are met:

    • The payment is a suspended payment. To do so, it compares the account POID in the flist with the account POID of the payment suspense account in the /config/psm object.

    • The payment is active.

    • The value of the PIN_FLD_FLAGS field is set to PIN_REVERSE_FLAG_REVERSE_AS_UNALLOCATED (1).

  4. Calls PCM_OP_BILL_REVERSE_PAYMENT to reverse the payment in the payment suspense account and create the associated objects in the database. For the /event/billing/reversal object, PIN_FLD_PAYMENT_TRANS_ID is set to the transaction ID of the suspended payment. This opcode populates the reversal flist with the payment's TRANS_ID value.

  5. Populates the payment batch with the sum of the reversal flist.

  6. Validates the reverse payment operation and creates the reversal batch event in the database.

The result of the reversal is returned in the PIN_FLD_RESULTS field of PCM_OP_BILL_REVERSE. The reversal will not be allowed if either of the following conditions is true:

  • The payment is not a suspended payment.

  • The payment is not an active payment.

How BRM Handles Mandate Information for SEPA Processing

The following sections describe how BRM handles mandate information.

How BRM Registers a Mandate

To register the mandate information provided during customer account creation, BRM uses PCM_OP_CUST_SET_PAYINFO.

PCM_OP_CUST_SET_PAYINFO takes as input the mandate information such as the customer's IBAN and BIC and the creditor identification code.

This opcode adds the mandate by:

  1. Creating a unique mandate reference number (UMR) for the mandate, if it is not provided in the input flist

  2. Setting the status of the mandate to active

  3. Creating the /payinfo/sepa object with the mandate information

PCM_OP_CUST_SET_PAYINFO calls PCM_OP_CUST_CREATE_PAYINFO, which calls PCM_OP_CUST_POL_VALID_PAYINFO, which validates that the format of the IBAN and BIC comply with the formats described in the SEPA rulebooks. Additional custom validations can be performed on the mandate information, such as country-specific validations.

How BRM Updates a Mandate

To update the mandate information, BRM uses the following opcodes:

  • PCM_OP_CUST_AMEND_MANDATE, to update the customer information

  • PCM_OP_CUST_AMEND_CREDITOR_INFO, to update the creditor information

PCM_OP_CUST_AMEND_MANDATE takes as input a reference to the /payinfo/sepa object and the mandate information to update.

This opcode updates the mandate by:

  1. Updating the /payinfo/sepa object with the new mandate information

  2. Updating the PIN_FLD_MANDATE_AMENDED field in the /payinfo/sepa object by using flags to indicate the fields that are amended

  3. Generating the /event/activity/sepa/mandate_amendment event to record the mandate update

PCM_OP_CUST_AMEND_CREDITOR_INFO takes as input the creditor ID to be updated and the new creditor ID and creditor name.

This opcode updates the creditor information by:

  1. Updating the /config/creditor object with the new creditor information

  2. Determining if any /payinfo/sepa object exists that is associated with the original creditor ID and updating the /payinfo/sepa object with the new creditor information

  3. In each /payinfo/sepa object that is updated, updating the PIN_FLD_MANDATE_AMENDED field by using flags to indicate the fields that are amended

  4. Generating the /event/activity/sepa/mandate_amendment event to record the update

Updating Creditor Information

To update the creditor information, use the PCM_OP_CUST_AMEND_CREDITOR_INFO opcode. This opcode updates the creditor name and the creditor ID only.

PCM_OP_CUST_AMEND_CREDITOR_INFO uses the creditor ID to update the /config/creditor object with the new creditor information.

Any update to a creditor configuration triggers automatic updates to all the mandates with this creditor ID in the BRM database. For example, if you have multiple customers that have mandates with the same creditor ID, BRM automatically locates the customers' payment information and updates their mandates with the new creditor information.

How BRM Cancels a Mandate

To cancel a mandate, BRM uses PCM_OP_CUST_CANCEL_MANDATE.

PCM_OP_CUST_CANCEL_MANDATE takes as input the reference to the /payinfo/sepa object that contains the mandate to cancel.

This opcode cancels the mandate by:

  1. Setting the PIN_FLD_MANDATE_STATUS field in the /payinfo/sepa object to PIN_MANDATE_STATUS_CANCELED

  2. Setting the PIN_FLD_MANDATE_END_T field to the current time to record the time of cancellation

  3. Calling PCM_OP_CUST_DELETE_PAYINFO to delete the /payinfo/sepa object. The opcode does not cancel the /payinfo/sepa object if it determines that it is associated with a bill unit or if a SEPA payment request is pending